您的位置:首页 > 其它

Educational Codeforces Round 22

2017-06-25 00:24 375 查看
Problems    
#Name  
A The Contest standard input/output 2 s, 256 MB    x1629
B The Golden Age standard input/output 1 s, 256 MB    x506
C The Tag Game standard input/output 1 s, 256 MB    x656
D Two Melodies standard input/output 2 s, 256 MB    x21
E Army Creation standard input/output 2 s, 256 MB    x92
F Bipartite Checking standard input/output 6 s, 256 MB    x25

A

水题 不解释

#include <bits/stdc++.h>
using namespace std;
int n,m,xx,yy,sum;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&xx),sum+=xx;
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&xx,&yy);
if(xx<=sum&&yy>=sum){printf("%d\n",sum);return 0;}
else if(sum<xx){printf("%d\n",xx);return 0;}
}puts("-1");
}

B

这题全是细节

要判有没有爆long long还有边界情况

#include <bits/stdc++.h>
using namespace std;
#define int long long
int x,y,l,r,ans;
set<int>s;
bool check(int x,int y){return log10(x)+log10(y)>18;}
signed main(){
scanf("%I64d%I64d%I64d%I64d",&x,&y,&l,&r);
for(int i=0,t=1;;i++,t=t*x){
if(t>r)break;
for(int j=0,w=1;;j++,w=w*y){
if(t+w>r)break;
if(t+w>=l)s.insert(t+w);
if(check(w,y))break;
}
if(check(t,x))break;
}
if(s.empty()){printf("%I64d\n",r-l+1);return 0;}
ans=max(*s.begin()-l,0ll);
for(set<int>::iterator it=s.begin(),it2;it!=s.end();it++){
it2=it;
if(it!=s.begin())it2--;
ans=max(ans,*it-*it2-1);
it2=it,it2++;
if(it2==s.end())ans=max(ans,r-*it);
}printf("%I64d\n",ans);
}

C

贪心

在不被追到的情况下走的最远

一遍DFS即可  (为什么题解全是2遍dfs的  难以理解)

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=400050;
int n,x,first
,nxt
,v
,tot,deep
,xx,yy,rec
,fa
,ans;
void add(int x,int y){v[tot]=y,nxt[tot]=first[x],first[x]=tot++;}
void dfs(int x){
for(int i=first[x];~i;i=nxt[i])if(v[i]!=fa[x])
fa[v[i]]=x,deep[v[i]]=deep[x]+1,dfs(v[i]),rec[x]=max(rec[x],rec[v[i]]+1);
}
int main(){
memset(first,-1,sizeof(first));
scanf("%d%d",&n,&x);
for(int i=1;i<n;i++)scanf("%d%d",&xx,&yy),add(xx,yy),add(yy,xx);
deep[1]=1,dfs(1);
ans=max(ans,(deep[x]-1+rec[x])*2);
for(int i=x,t=0;;i=fa[i],t++){
if(deep[x]-t*2<2)break;
ans=max(ans,(deep[i]-1)*2+rec[i]*2);
}printf("%d\n",ans);
}

D

DP

f[i][j] A选a[i] B选[j]的最长长度

维护两个数组 X[i]表示mod 7 为i的最长长度

Y[i]表示数字是i的最长长度

为了去重

只从i<j转移   更新i>j的情况

if(i<j)ans=max(ans,f[j][i]=f[i][j]=max(max(Y[a[j]+1],max(Y[a[j]-1],X[a[j]%7])),f[i][0])+1);
X[a[j]%7]=max(X[a[j]%7],f[i][j]),Y[a[j]]=max(Y[a[j]],f[i][j]);
//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=5050;
int f

,a
,n,X[7],Y[100500],ans;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=0;i<=n;i++){
memset(X,0,sizeof(X)),memset(Y,0,sizeof(Y));
for(int j=1;j<=n;j++){
if(i==j)continue;
if(i<j)ans=max(ans,f[j][i]=f[i][j]=max(max(Y[a[j]+1],max(Y[a[j]-1],X[a[j]%7])),f[i][0])+1);
X[a[j]%7]=max(X[a[j]%7],f[i][j]),Y[a[j]]=max(Y[a[j]],f[i][j]);
}
}
printf("%d\n",ans);
}

E

一个点有没有被算到答案里  

只跟它k次之前出现的地方有没有小于l有关

那  主席树直接上

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=100050;
vector<int>vec
;
int n,k,q,xx,yy,a
,jy,s
,lson[N*66],rson[N*66],tree[N*66],cnt,root
,lst;
void insert(int l,int r,int &pos,int last,int wei){
pos=++cnt;tree[pos]=tree[last]+1;
if(l==r)return;
int mid=(l+r)>>1;
if(mid<wei)lson[pos]=lson[last],insert(mid+1,r,rson[pos],rson[last],wei);
else rson[pos]=rson[last],insert(l,mid,lson[pos],lson[last],wei);
}
int query(int l,int r,int pos,int last,int L,int R){
if(l>=L&&r<=R)return tree[pos]-tree[last];
int mid=(l+r)>>1;
if(mid<L)return query(mid+1,r,rson[pos],rson[last],L,R);
else if(mid>=R)return query(l,mid,lson[pos],lson[last],L,R);
else return query(l,mid,lson[pos],lson[last],L,R)+query(mid+1,r,rson[pos],rson[last],L,R);
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
vec[a[i]].push_back(i),jy=vec[a[i]].size()-1;
s[i]=jy>=k?vec[a[i]][jy-k]:0,insert(0,N,root[i],root[i-1],s[i]);
}
scanf("%d",&q);
while(q--){
scanf("%d%d",&xx,&yy),xx=(xx+lst)%n+1,yy=(yy+lst)%n+1;
if(xx>yy)swap(xx,yy);
printf("%d\n",lst=query(0,N,root[yy],root[xx-1],0,xx-1));
}
}

F

BZOJ 4025

并查集+cdq分治

我打的是线段树+vector

最后DFS一遍

效果一样

 

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=100050;
int n,q,f
,top,size
,dis
;
struct Edge{int from,to,tim;Edge(){}Edge(int x,int y){from=x,to=y;}}edge
;
struct Update{int fx,fy,disx;Update(){}Update(int x,int y,int z){fx=x,fy=y,disx=z;}}upd
;
bool operator<(Edge a,Edge b){if(a.from!=b.from)return a.from<b.from;return a.to<b.to;}
set<Edge>st;set<Edge>::iterator it;vector<Edge>vec[N*8];
void insert(int l,int r,int pos,int L,int R,Edge t){
if(l>=L&&r<=R){vec[pos].push_back(t);return;}
int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
if(mid<L)insert(mid+1,r,rson,L,R,t);
else if(mid>=R)insert(l,mid,lson,L,R,t);
else insert(l,mid,lson,L,R,t),insert(mid+1,r,rson,L,R,t);
}
int find(int x){return x==f[x]?x:find(f[x]);}
void merge(int x,int y,int z){
if(size[x]>size[y])swap(x,y);
upd[++top]=Update(x,y,dis[x]);
f[x]=y,dis[x]=z,size[y]+=size[x];
}
bool get_dis(int x){
int r=0;
while(f[x]!=x)r^=dis[x],x=f[x];
return r;
}
void query(int l,int r,int pos){
int rec=top;
for(int i=0;i<vec[pos].size();i++){
int x=find(vec[pos][i].from),y=find(vec[pos][i].to),z=get_dis(vec[pos][i].from)^get_dis(vec[pos][i].to)^1;
if(x!=y)merge(x,y,z);
else if(z&1){for(int j=l;j<=r;j++)puts("NO");goto ed;}
}
if(l==r)puts("YES");
else query(l,(l+r)>>1,pos<<1),query((l+r)/2+1,r,pos<<1|1);
ed:for(int i=top;i>rec;i--){
int fx=upd[i].fx,fy=upd[i].fy;
dis[fx]=0,f[fx]=fx,size[fy]-=size[fx];
}top=rec;
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=q;i++){
scanf("%d%d",&edge[i].from,&edge[i].to);edge[i].tim=i;
if((it=st.find(edge[i]))==st.end())st.insert(edge[i]);
else insert(1,q,1,it->tim,i-1,edge[i]),st.erase(it);
}
for(it=st.begin();it!=st.end();it++)insert(1,q,1,it->tim,q,*it);
query(1,q,1);
}

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: