Codeforces Round #312 (Div. 2) A B C D E

来源:互联网 发布:js可以控制浏览器比例 编辑:程序博客网 时间:2024/05/16 01:47

A Lala Land and Apple Trees

        模拟。

#include <bits/stdc++.h>  using namespace std;  #define ll long longpair<int,int> a[110];int main(){int n;cin>>n;a[0]=make_pair(0,0);for(int i=1;i<=n;i++){int x,y;cin>>x>>y;a[i]=make_pair(x,y);}sort(a,a+n+1);int k;for(k=0;k<=n;k++){if(a[k].first==0)break;}int p=0;int ans=0;while(1){p++;if(k+p>n)break;if(k-p<0)break;ans+=a[k+p].second;ans+=a[k-p].second;}if(k+p<=n)ans+=a[k+p].second;if(k-p>=0)ans+=a[k-p].second;cout<<ans<<endl;return 0;}

Amr and The Large Array

        尺取法。

#include <bits/stdc++.h>  using namespace std;  #define ll long longint cnt[1000010];int a[100010];int main(){int n;cin>>n;int MAX=0;for(int i=1;i<=n;i++){scanf("%d",&a[i]);cnt[a[i]]++;MAX=max(MAX,cnt[a[i]]);}int l=0,r=0;int cur=0;memset(cnt,0,sizeof(cnt));int ans=1e9;int ansl,ansr;while(1){if(cur<MAX){r++;if(r>n)break;cnt[a[r]]++;cur=max(cur,cnt[a[r]]);}else{if(r-l<ans){ans=r-l;ansr=r;ansl=l;}l++;cnt[a[l]]--;if(cnt[a[l]]==MAX-1){cur--;}}}cout<<ansl+1<<" "<<ansr<<endl;return 0;}

C Amr and Chemistry

        n个数,每次对一个数操作。共有两种操作,乘以2和整除2。问最少要多少次操作,才能使得所有n个数相等。

        暴力。对于某个数来说,它通过操作得到100000以内的数的数量,最多是log^2(100000)。我们就可以通过二重循环计算出它可以到达的所有数需要的最少步。然后考察一下所有数都能达到的那些数,找一个最小的答案。

#include <bits/stdc++.h>  using namespace std;  #define ll long longusing namespace std;int a[100010];int cnt[100010];//统计n个数中有多少数能得到i int ans[100010];int main(){int n;cin>>n;for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<=n;i++){int rightcarry=0;//先右移再左移,枚举右移量 while(1){int tmp=a[i];tmp>>=rightcarry;if(tmp==0)break;cnt[tmp]++;ans[tmp]+=rightcarry;if(rightcarry){if( (a[i]>>(rightcarry-1)) == (tmp<<1) ){rightcarry++;continue;}}int c=0;while(1){c++;tmp<<=1;if(tmp>100000)break;cnt[tmp]++;ans[tmp]+=(rightcarry+c);}rightcarry++;}}int re=1e9;for(int i=1;i<=100000;i++){if(cnt[i]==n){//有数得不到i的时候忽略 if(ans[i]<re)re=ans[i];}}cout<<re<<endl;return 0;}


D Guess Your Way Out! II

        高度为h的满二叉树。节点从上到下从左到右编号,从根开始沿着某路径往下走直到叶子。有q个询问,每个询问获得的信息是在第i层有没有经过区间[l,r]。判断询问的答案是否矛盾,以及询问是否足够充分得到唯一的结果。

        把Yes和No的两种询问分开,lr双关键字升序排序。先处理回答为Yes的询问,如果得到了不唯一的区间,就是矛盾的。然后处理回答为No的询问,去缩小那个区间,如果区间缩小为1,就是有唯一解,否则询问不够充分。最后还要判一遍矛盾,即判断Yes的回答是否都被满足。有很多要注意的细节,见代码。

#include <bits/stdc++.h> using namespace std;#define ll long longstruct node{ll l,r;;node(){}node(ll l,ll r):l(l),r(r){}bool operator<(const node& other)const{if(l==other.l)return r<other.r;return l<other.l;}};node Yes[100010];node No[100010];int main(){int h,q;cin>>h>>q;int pYes=0;int pNo=0;for(int i=1;i<=q;i++){int x,ans;ll l,r;scanf("%d%I64d%I64d%d",&x,&l,&r,&ans);//弄到最下一层 for(int hh=x;hh<h;hh++){l<<=1;r<<=1;r|=1;}if(ans){pYes++;Yes[pYes].l=l;Yes[pYes].r=r;}else{pNo++;No[pNo].l=l;No[pNo].r=r;}}sort(Yes+1,Yes+pYes+1);sort(No+1,No+pNo+1);bool cheated=0;bool mulsol=0;set<node> ans;//因为矛盾优先级比不唯一高,所以需要记录所有可能答案 //处理Yes询问 ll l=Yes[1].l,r=Yes[1].r;for(int i=2;i<=pYes;i++){if(Yes[i].l>r){cheated=1;}else{l=Yes[i].l;r=min(r,Yes[i].r);}}if(pYes==0){//如果没有Yes询问,所有叶子都有可能 l=1LL<<(h-1);r=(1LL<<(h))-1;}//处理No询问 for(int i=1;i<=pNo;i++){if(i<pNo&&No[i].r>=No[i+1].l){No[i+1].l=No[i].l;No[i+1].r=max(No[i].r,No[i+1].r);continue;}if(No[i].r<l){continue;}else{if(No[i].l>l){//这里要特别注意,不能越过r ans.insert(node(l,min(r,No[i].l-1) ));}l=No[i].r+1;if(l>r)break;}}//补上可能漏掉的区间 if(l<=r)ans.insert(node(l,r));for(int i=1;i<=pYes;i++){set<node>::iterator it=ans.lower_bound(Yes[i]);bool ok=0;if(it!=ans.end()&&it->l<=Yes[i].r){ok=1;}if(it!=ans.begin()){it--;if(it->r>=Yes[i].l)ok=1;}if(!ok){cheated=1;break;}}ll re;if(ans.size()==1&&ans.begin()->l==ans.begin()->r){re=ans.begin()->l;}else{mulsol=1;}if(ans.size()==0)cheated=1;if(cheated){cout<<"Game cheated!"<<endl;}else if(mulsol){cout<<"Data not sufficient!"<<endl;}else{cout<<re<<endl;}return 0;}


E A Simple Task

        一个字符串,包含小写字母,有q次操作,每次操作升序或者降序排序一个区间。求操作完后的串。

        对26个字符分别建线段树,维护区间有多少该字符。维护方法是使用类似计数排序的方法,如升序排序,查询区间中有多少'a',放到最前面,再查询bcd...

#include <bits/stdc++.h>      using namespace std;    #define ll long long struct node{int l,r;int val;int lazy;//}tree[26][400010];char str[100010];void push_up(int which,int n){tree[which][n].val = tree[which][n<<1].val+tree[which][(n<<1)|1].val;}void push_down(int which,int n){int val=tree[which][n].val;if(tree[which][n].l==tree[which][n].r)return;if(tree[which][n].lazy==-1){int llen=tree[which][n<<1].r-tree[which][n<<1].l+1;if(val>llen){tree[which][n<<1].val=llen;tree[which][(n<<1)|1].val=val-llen;}else{tree[which][n<<1].val=val;tree[which][(n<<1)|1].val=0;}}if(tree[which][n].lazy==1){int rlen=tree[which][(n<<1)|1].r-tree[which][(n<<1)|1].l+1;if(val>rlen){tree[which][(n<<1)|1].val=rlen;tree[which][n<<1].val=val-rlen;}else{tree[which][(n<<1)|1].val=val;tree[which][n<<1].val=0;}}tree[which][n<<1].lazy=tree[which][n].lazy;tree[which][(n<<1)|1].lazy=tree[which][n].lazy;tree[which][n].lazy=0;}void build_tree(int which,int n,int l,int r){tree[which][n].l=l;tree[which][n].r=r;if(l==r){if(str[l]==which+'a'){tree[which][n].val=1;}return;}int mid=(l+r)>>1;build_tree(which,n<<1,l,mid);build_tree(which,(n<<1)|1,mid+1,r);push_up(which,n);}int query(int which,int n,int l,int r){if(tree[which][n].l==l&&tree[which][n].r==r){return tree[which][n].val;}int mid=(tree[which][n].l+tree[which][n].r)>>1;if(tree[which][n].lazy){push_down(which,n);}if(r<=mid){return query(which,n<<1,l,r);}else{if(l>mid){return query(which,(n<<1)|1,l,r);}else{return query(which,n<<1,l,mid)+query(which,(n<<1)|1,mid+1,r);}}}void update(int which,int n,int l,int r,int val,int lr){if(l>r)return;if(tree[which][n].l==l&&tree[which][n].r==r){tree[which][n].lazy=lr;tree[which][n].val=val;return;}int mid=(tree[which][n].l+tree[which][n].r)>>1;if(tree[which][n].lazy){push_down(which,n);}if(r<=mid){update(which,n<<1,l,r,val,lr);}else{if(l>mid){update(which,(n<<1)|1,l,r,val,lr);}else{if(lr==-1){//升序 int lval=min(val,tree[which][n<<1].r-l+1);int rval=val-lval;update(which,n<<1,l,mid,lval,lr);update(which,(n<<1)|1,mid+1,r,rval,lr);}else{//降序 int rval=min(val,r-tree[which][(n<<1)|1].l+1);int lval=val-rval;update(which,(n<<1)|1,mid+1,r,rval,lr);update(which,n<<1,l,mid,lval,lr);}}}push_up(which,n);}int main(){int n,q;cin>>n>>q;scanf("%s",str+1);for(int i=0;i<26;i++){build_tree(i,1,1,n);}for(int i=1;i<=q;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);int cnt[26]; for(int ch=0;ch<26;ch++){cnt[ch]=query(ch,1,x,y); }int l=x,r=y;if(z==0){//降序 for(int ch=0;ch<26;ch++){if(cnt[ch]==0)continue;update(ch,1,r-cnt[ch]+1,r,cnt[ch],1);update(ch,1,r+1,y,0,1);r-=cnt[ch];update(ch,1,x,r,0,1);}}else{//升序 for(int ch=0;ch<26;ch++){if(cnt[ch]==0)continue;update(ch,1,l,l+cnt[ch]-1,cnt[ch],-1);update(ch,1,x,l-1,0,-1);l+=cnt[ch];update(ch,1,l,y,0,-1);}}}for(int i=1;i<=n;i++){for(int ch=0;ch<26;ch++){if(query(ch,1,i,i)){str[i]=ch+'a';break;}}}printf("%s\n",str+1);return 0;}


0 0
原创粉丝点击