Noip模拟78 2021.10.16
这次时间分配还是非常合理的,但可惜的是$T4$没开$\textit{long long}$挂了$20$
但是$Arbiter$上赏了蒟蒻$20$分,就非常不错~~~
T1 F
直接拿暴力水就可以过,数据无法精心构造,根本卡不掉,除非测评姬像老奶奶(详情见这一篇)
考场经过
造个大的数据试试跑几秒........
woc,2.7秒,不行,还是得卡常.......
(30min later.....)
终于1.4秒了,就这样吧,拿个60分走人.....不对,这题时限4秒........
然后就比较自信的把这题扔了
所以直接放码了,应该都能想到
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 namespace AE86{ 5 inline int read(){ 6 int x=0,f=1;char ch=getchar(); 7 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 8 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; 9 }inline void write(int x,char opt='\n'){ 10 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-'); 11 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); 12 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 13 }using namespace AE86; 14 const int NN=2005; 15 int n,a[NN],b[NN]; 16 int stk[NN],top; 17 int ans,f[4000005],tmp; 18 int num[4000005],cnt; 19 unordered_map<int,int> mp; 20 set<int> s; 21 namespace WSN{ 22 inline short main(){ 23 freopen("f.in","r",stdin); 24 freopen("f.out","w",stdout); 25 n=read(); 26 for(int i=1;i<=n;++i) a[i]=read(); 27 for(int i=1;i<=n;++i) b[i]=read(),s.insert(b[i]); 28 for(int i=1;i<=n;++i) for(int j=1;j<=n;++j){ 29 tmp=(a[i]^b[j]); 30 if(mp.find(tmp)==mp.end()){ 31 mp[tmp]=++cnt; 32 num[cnt]=tmp; 33 } 34 } 35 for(int j=1;j<=cnt;j++){ 36 for(int i=1;i<=n;++i){ 37 tmp=(num[j]^a[i]); 38 if(s.find(tmp)!=s.end()) s.erase(s.find(tmp)),stk[++top]=tmp; 39 else break; 40 } 41 if(s.empty()) f[++ans]=num[j]; 42 while(top) s.insert(stk[top--]); 43 } 44 write(ans); if(!ans) return 0; 45 sort(f+1,f+ans+1); 46 for(int i=1;i<=ans;i++) write(f[i],' '); 47 puts(""); 48 return 0; 49 } 50 } 51 signed main(){return WSN::main();}
T2 S
爆搜$\huge{差亿点}$碾标算,但是能拿$70$我反正没想到
随便说一下暴力思路吧
就是暴力搜出来所有可能的不丑的字符串(搜的过程中正常剪枝,剪掉不合法的就行)
然后考虑在开始的时候给初始字符串标号为$1,2,3,4,5$,拿样例$RRGYY$举例
那么可能的一组不丑的串最后长成$RYGRY$,他的标号就是$1,4,3,2,5$,然后按照标号求逆序对个数就是交换次数
和正解的$dp$思路差不多,只不过不用爆搜,改成了冻龟
冻龟还没写对,放个暴力跑了
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 #define int long long 7 using namespace std; 8 namespace AE86{ 9 #define out(x) cout<<#x<<"="<<(x)<<endl 10 inline int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; 14 }inline void write(int x,char opt='\n'){ 15 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-'); 16 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); 17 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 18 }using namespace AE86; 19 const int NN=405; 20 int n,a[NN],R,G,Y,b[NN];//18 7 25 21 char s[NN]; 22 int ans=0x3fffffff; 23 vector<int> pre,bin[27],cun[27]; 24 struct BIT{ 25 int c[NN]; 26 inline int lowbit(int x){return x&(-x);} 27 inline void update(int x,int v){for(int i=x+1;i<NN;i+=lowbit(i))c[i]+=v;} 28 inline int query(int x,int ans=0){for(int i=x+1;i;i-=lowbit(i))ans+=c[i];return ans;} 29 }tr; 30 inline void dfs(int cR,int cG,int cY,int last){ 31 if(cR+cG+cY==n){ 32 // for(int i=0;i<pre.size();i++){ 33 // char ch=(char)(pre[i]+'A'-1); 34 // cout<<ch; 35 // }cout<<" "; 36 memset(tr.c,0,sizeof(tr.c)); 37 for(int i=0;i<pre.size();++i){ 38 if(pre[i]==18) b[i+1]=bin[18].back(),bin[18].pop_back(); 39 if(pre[i]==7) b[i+1]=bin[7].back(),bin[7].pop_back(); 40 if(pre[i]==25) b[i+1]=bin[25].back(),bin[25].pop_back(); 41 } bin[18]=cun[18]; bin[25]=cun[25]; bin[7]=cun[7]; 42 // for(int i=1;i<=n;i++) cout<<b[i]<<" ";cout<<endl; 43 int tmp=0; 44 for(int i=n;i;--i){tmp+=tr.query(b[i]-1);tr.update(b[i],1);} 45 ans=min(ans,tmp); 46 return; 47 } 48 if(last!=18&&cR+1<=R){pre.push_back(18);dfs(cR+1,cG,cY,18);pre.pop_back();} 49 if(last!=7&&cG+1<=G){pre.push_back(7);dfs(cR,cG+1,cY,7);pre.pop_back();} 50 if(last!=25&&cY+1<=Y){pre.push_back(25);dfs(cR,cG,cY+1,25);pre.pop_back();} 51 } 52 namespace WSN{ 53 inline short main(){ 54 freopen("s.in","r",stdin); 55 freopen("s.out","w",stdout); 56 n=read(); scanf("%s",s+1); 57 for(int i=n;i;i--){ 58 a[i]=(int)(s[i]-'A'+1); 59 if(s[i]=='R') ++R,bin[18].push_back(i); 60 if(s[i]=='G') ++G,bin[7].push_back(i); 61 if(s[i]=='Y') ++Y,bin[25].push_back(i); 62 } 63 if(max(R-G-Y-2,max(G-R-Y-2,Y-R-G-2))>=0) return puts("-1"),0; 64 cun[18]=bin[18]; cun[7]=bin[7]; cun[25]=bin[25]; 65 dfs(0,0,0,0); 66 write(ans); 67 return 0; 68 } 69 } 70 signed main(){return WSN::main();}
T3 Y
神仙计数冻龟(发现冻龟这个词比较$dei$,以后不打$dp$了,每次还得写两个$。。。)
记$h_i\in [0,a_i]$表示第$i$个人给出去的球
考虑什么时候序列$B$本质不同,实际上是在$h$的差分序列不同的时候
因为如果有$\forall h_i>1$,一定可以使最小的$h_i$变成$0$,每个人少得到一点,少付出一点,结果是相等的(黑暗哲学?)
知道这个就有这道题的基本思路了,剩下的只能推荐一篇博客了,因为写得太好,我写的话也没有人家的清楚
不如直接看最清楚的解释,戳这里!
T4 O
询问离线并按照时间排序,线段树维护答案$\sum \max\limits_{i-t\leq j \leq i} a_j$
建立递减单调栈找到一个时间都可以更新哪些点,用$vector$存起来,单调栈内的元素都是$log$级别的,可以存下
然后每组询问把线段树更新到当前时间然后查询就行
1 #include<cmath> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 #define lid (id<<1) 8 #define rid (id<<1|1) 9 #define int long long 10 using namespace std; 11 namespace AE86{ 12 #define out(x) cout<<#x<<"="<<(x)<<endl 13 inline int read(){ 14 int x=0,f=1;char ch=getchar(); 15 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 16 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f; 17 }inline void write(int x,char opt='\n'){ 18 char ch[20];int len=0;if(x<0)x=~x+1,putchar('-'); 19 do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x); 20 for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 21 }using namespace AE86; 22 const int NN=2e5+5; 23 int n,a[NN],q,stk[NN],top; 24 struct query{int t,l,r,id;}p[NN]; 25 struct SNOWtree{ 26 int ll[NN<<2],rr[NN<<2],sum[NN<<2]; 27 inline void pushup(int id){ 28 if(ll[id]==rr[id]) return;sum[id]=sum[lid]+sum[rid]; 29 } 30 inline void build(int id,int l,int r){ 31 ll[id]=l; rr[id]=r;if(l==r) return sum[id]=a[l],void(); 32 int mid=l+r>>1;build(lid,l,mid); build(rid,mid+1,r);pushup(id); 33 } 34 inline void update(int id,int pos,int v){ 35 if(ll[id]==rr[id]) return sum[id]=v,void();int mid=ll[id]+rr[id]>>1; 36 if(pos<=mid) update(lid,pos,v);else update(rid,pos,v);pushup(id); 37 } 38 inline int query(int id,int l,int r){ 39 if(l<=ll[id]&&rr[id]<=r) return sum[id]; 40 int mid=ll[id]+rr[id]>>1,ans=0; 41 if(l<=mid) ans+=query(lid,l,r); 42 if(r>mid) ans+=query(rid,l,r); 43 return ans; 44 } 45 }tr; 46 vector<pair<int,int> > upd[NN]; 47 int ans[NN]; 48 namespace WSN{ 49 inline short main(){ 50 freopen("o.in","r",stdin);freopen("o.out","w",stdout); 51 n=read();q=read();for(int i=1;i<=n;i++)a[i]=read(); 52 for(int i=1;i<=q;i++)p[i].t=read(),p[i].l=read(),p[i].r=read(),p[i].id=i; 53 sort(p+1,p+q+1,[](query a,query b)->bool{return a.t<b.t;}); 54 for(int i=1;i<=n;i++){ 55 while(top&&a[stk[top]]<=a[i]) --top; stk[++top]=i; 56 for(int j=1;j<=top-1;j++) upd[i-stk[j]].push_back(make_pair(i,a[stk[j]])); 57 } 58 tr.build(1,1,n); 59 for(int o=1;o<=q;o++){ 60 if(p[o].t!=p[o-1].t) 61 for(int i=p[o-1].t+1;i<=p[o].t;i++) for(auto x:upd[i]) 62 tr.update(1,x.first,x.second); 63 ans[p[o].id]=tr.query(1,p[o].l,p[o].r); 64 } 65 for(int i=1;i<=q;i++) write(ans[i]); 66 return 0; 67 } 68 } 69 signed main(){return WSN::main();}