由于CF的比赛时间实在是有点晚,最近开启了AtCoder的比赛生涯.
Beginner的题目有点类似CF里的Div3.甚至要更简单一点.主要是题目给的样例基本上能把BUG都找出来.
A是语法题.
B是数学题.要注意的是尽量控制精度到题目给定误差的范围那里.不然会WA
太水就不给代码了
C是简单dfs.注意一下回到1的时候要把耗时也给加上就行了.
参考代码:
int t[10][10];
int K,vis[10],n,ans;
void dfs(int pre,int k,int val){
if(k == n+1){
if(val + t[pre][1] == K) ans++;
return;
}
fir(i,2,n){
if(vis[i]) continue;
vis[i] = 1;
dfs(i,k+1,val+t[pre][i]);
vis[i] = 0;
}
}
int main(){
cin >> n >> K;
fir(i,1,n){
fir(j,1,n){
cin >> t[i][j];
}
}
vis[1] = 1;
dfs(1,2,0);
cout << ans;
return 0;
}
D 这题的难度在于读懂题目…其实就是给了一个区间加的操作,最后加完询问每个点是否都小于给定的W.一个树状数组即可水过去.注意一下区间不不包括T[i]的
参考代码:
int s[N],t[N],n,w;
LL c[N],p[N];
void add(int p,int v){
for(;p<=2e5+1;p+=p&-p) c[p] += v;
}
LL ask(int p){
LL res = 0;
for(;p;p-=p&-p) res += c[p];
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> w;
fir(i,1,n){
cin >> s[i] >> t[i] >> p[i];
s[i]++;
t[i]++;
add(t[i],-p[i]);
add(s[i],p[i]);
}
fir(i,0,2e5){
if(ask(i) > w){
cout << "No\n";
return 0;
}
}
cout << "Yes\n";
return 0;
}
E 一个简单的DP问题.考虑到每个点都能从上方,左上方,左方的任意一个点转移过来,我们多维护一个sum数组维护一下前缀和即可.
注意一下虽然1e9相加不会爆int,但能开long long还是开long long吧.
参考代码:
const int p = 1e9+7;
string mz[2020];
LL dp[2020][2020],sum[2020][2020][3];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin >> n >> m;
fir(i,1,n){
cin >> mz[i];
mz[i] = ' ' + mz[i];
}
dp[1][1] = 1;
fir(i,1,n){
fir(j,1,m){
if(mz[i][j] == '#') continue;
if(i != 1 || j != 1) dp[i][j] = (sum[i-1][j][0] + sum[i][j-1][1] + sum[i-1][j-1][2])%p;
sum[i][j][0] = (dp[i][j]+sum[i-1][j][0])%p;
sum[i][j][1] = (dp[i][j]+sum[i][j-1][1])%p;
sum[i][j][2] = (dp[i][j]+sum[i-1][j-1][2])%p;
}
}
cout << dp[n][m] << "\n";
return 0;
}
F 启发式合并的裸题.每个人开一个动态的线段树即可.合并的时候把小的合并到大的里面,复杂度O(nlogn). 线段树合并博客
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int fa[N],siz[N],root[N],n,m,a[N];
namespace seg{
int tot,sum[N*20],ls[N*20],rs[N*20];
void add(int &now,int l,int r,int p,int v){
if(!now) now = ++ tot;
sum[now]+=v;
if(l == r) return;
int mid = l + r >> 1;
if(p <= mid) add(ls[now],l,mid,p,v);
else add(rs[now],mid+1,r,p,v);
}
int ask(int now,int l,int r,int p){
if(!now) return 0;
if(l == r) return sum[now];
int mid = l + r >> 1;
if(p <= mid) return ask(ls[now],l,mid,p);
return ask(rs[now],mid+1,r,p);
}
int merge(int x,int y){
if(!x || !y) return x+y;
sum[x] += sum[y];
ls[x] = merge(ls[x],ls[y]);
rs[x] = merge(rs[x],rs[y]);
return x;
}
}
int get(int x){
int r = x;
while(fa[r] != r) r = fa[r];
int i=x,j=x;
while(i != r){
j = fa[i];
fa[i] = r;
i = j;
}
return r;
}
void merge(int x,int y){
int fx = get(x),fy = get(y);
if(siz[fx] > siz[fy]) return (void)merge(y,x);
if(fx != fy){
fa[fx] = fy;
siz[fy] += siz[fx];
root[y] = seg::merge(root[fy],root[fx]);
}
}
int query(int x,int y){
int fx = get(x);
return seg::ask(root[fx],1,n,y);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
fir(i,1,n){
cin >> a[i];
siz[i] = 1;
fa[i] = i;
seg::add(root[i],1,n,a[i],1);
}
fir(i,1,m){
int op,a,b;
cin >> op >> a >> b;
if(op == 1) merge(a,b);
else cout << query(a,b) << "\n";
}
return 0;
}