https://codeforces.com/contest/1234/problem/D
写了个巨蠢的线段树(不愧是垃圾),有必要提醒下自己这种题怎么做
#include<iostream> #include<cstdio> #include<string> #include<set> #include<algorithm> using namespace std; const int maxn = 32; set<int> st[maxn]; int main() { string words; cin>>words; words = '.' + words; int len = words.size() - 1; for(int i=1;i<=len;++i) st[words[i]-'a'].insert(i); int q,cmd,pos,l,r; char ch; scanf("%d",&q); for(int k=0;k!=q;++k) { scanf("%d",&cmd); if(cmd==1) { scanf("%d",&pos); getchar(); scanf("%c",&ch); st[words[pos]-'a'].erase(pos); words[pos] = ch; st[words[pos]-'a'].insert(pos); }else{ int ans = 0; scanf("%d%d",&l,&r); for(int i=0;i!=26;++i) { auto it = st[i].lower_bound(l);//MDZZ 再也不直接用algorithm的二分了,容器内的快多了,佛了 if(it == st[i].end()) continue;//找到大于等于l开始的字符,因为不重复,所以只需要找出一个就好了(ORZ) int x = *it; if(x <= r) ++ans; } cout<<ans<<' '; } } }
https://codeforces.com/contest/1234/problem/C
简单实现
#include<bits/stdc++.h> using namespace std; const int maxn = 2e5 + 32; int dp[3][maxn]; int q,n; void solve() { int l = 1,r = 1,k = 1; while(1) { if(l>n) { if(r==2) { cout<<"YES"<<' '; return; } cout<<"NO"<<' '; return; } if(k==1&&dp[r][l]==1) {++l;}else if(k==1&&dp[r][l]==2) {r = 3 - r; k = 2;}else { if(dp[r][l]!=2) { cout<<"NO"<<' '; return; }else{ ++l; k = 1; } } } } int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); cin >> q; while(q--) { cin >> n; char ch; for(int i=1;i<=2;++i) { for(int j=1;j<=n;++j) { cin>>ch; if(ch=='1'||ch=='2') dp[i][j] = 1; else dp[i][j] = 2; } } solve(); } }
垃圾如我,哭啦