Educational Codeforces Round 96 (Rated for Div. 2) de
You have a stringssconsisting ofnncharacters. Each character is either0or1.
You can perform operations on the string. Each operation consists of two steps:
- select an integeriifrom11to the length of the stringss, then delete the charactersisi(the string length gets reduced by11, the indices of characters to the right of the deleted one also get reduced by
- if the stringssis not empty, delete the maximum length prefix consisting of the same characters (the indices of the remaining characters and the string length get reduced by the length of the deleted prefix).
Note that both steps are mandatory in each operation, and their order cannot be changed.
For example, if you have a strings=s=111010, the first operation can be one of the following:
- selecti=1i=1: we'll get111010→→11010→→010;
- selecti=2i=2: we'll get111010→→11010→→010;
- selecti=3i=3: we'll get111010→→11010→→010;
- selecti=4i=4: we'll get111010→→11110→→0;
- selecti=5i=5: we'll get111010→→11100→→00;
- selecti=6i=6: we'll get111010
You finish performing operations when the stringssbecomes empty. What is the maximum number of operations you can perform?
InputThe first line contains a single integertt(1≤t≤10001≤t≤1000)— the number of test cases.
The first line of each test case contains a single integernn(1≤n≤2⋅1051≤n≤2⋅105)— the length of the stringss.
The second line contains stringssofnncharacters. Each character is either0or1.
It's guaranteed that the total sum ofnnover test cases doesn't exceed2⋅1052⋅105.
OutputFor each test case, print a single integer— the maximum number of operations you can perform.
Example input Copy5 6 111010 1 0 1 1 2 11 6 101010output Copy
3 1 1 1 3Note
In the first test case, you can, for example, selecti=2i=2and get string010after the first operation. After that, you can selecti=3i=3and get string1. Finally, you can only selecti=1i=1and get empty string.
題意(魔改=.=):
給出一個0和1組成的字串,玩家1先走,玩家2後走,玩家1要刪除任意一個字元,玩家2刪除頭部的一個字元或多個字元(011------11,00011--------11)。問玩家1最多刪除多少字元。
思路:暴力模擬,指標運用,思維。有連續先刪除連續字元段,沒有連續字元段 就從前往後刪。
程式碼:
#include<bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { int n; cin>>n; string s; cin>>s; int v[200005]= {0}; s[n]='#'; int k=0,l=1,y=-1; for(int i=0; i<n; i++) { if(s[i]==s[i+1]) { l++; } else { if(l>1) y=k; v[k]=l; k++; l=1; } } /* for(int i=0; i<k; i++) cout<<v[i]; cout<<endl; cout<<"y "<<y<<endl;*/ long long ans=0; int ii=0,jj=1,p=1; if(y==-1) p=0; for(int i=0; i<k; i++) { /*cout<<i<<" "<<jj<<" "<<ans<<" "<<p<<endl; for(int kk=0; kk<k; kk++) cout<<v[kk]; cout<<endl;*/ if(i>=jj) jj=i; ans++; if(v[i]>1) { ans++; } else { if(p==1) { for(int j=jj; j<k; j++) { if(v[j]>1) { ans++; v[j]--; jj=j; break; } if(j==k-1&&v[j]<=1) { if(i+1<k) { ans++; i++; } p=0; } } } else { if(i+1<k) { ans++; i++; // cout<<"!"<<endl; } } } } cout<<(ans+1)/2<<endl; } return 0; }View Code E. String Reversal time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output
You are given a stringss. You have to reverse it — that is, the first letter should become equal to the last letter before the reversal, the second letter should become equal to the second-to-last letter before the reversal — and so on. For example, if your goal is to reverse the string "abddea", you should get the string "aeddba". To accomplish your goal, you can swap theneighboring elements of the string.
Your task is to calculate the minimum number of swaps you have to perform to reverse the given string.
InputThe first line contains one integernn(2≤n≤2000002≤n≤200000) — the length ofss.
The second line containsss— a string consisting ofnnlowercase Latin letters.
OutputPrint one integer — the minimum number of swaps of neighboring elements you have to perform to reverse the string.
Examples input Copy5 aaazaoutput Copy
2input Copy
6 cbaabcoutput Copy
0input Copy
9 icpcsguruoutput Copy
30Note
In the first example, you have to swap the third and the fourth elements, so the string becomes "aazaa". Then you have to swap the second and the third elements, so the string becomes "azaaa". So, it is possible to reverse the string in two swaps.
Since the string in the second example is a palindrome, you don't have to do anything to reverse it.
題意:一個字串顛倒過來,最少需要氣泡排序多少次。
思路:樹狀陣列
(考慮每個位置的貢獻,從最後一個字元開始計算。
顯然對於相同的字元選取靠前的位置的貢獻更小。
所以用佇列維護相同字母的位置。
從後往前遍歷,然後用樹狀陣列維護到當前位置有多少位置沒排好,每排好一個位置就更新樹狀陣列,每個位置的貢獻就是query(pos)−1。
此時更新樹狀陣列的正確性是因為:在pos之前的位置整體向右移動一位,然後又因為pos移到他們的前面,抵消了,而p o s pospos後的位置,因為前面少一個位置,所以對應的樹狀陣列減1.)
學習借鑑:https://blog.csdn.net/weixin_45750972/article/details/109024382
程式碼:
#include<bits/stdc++.h> using namespace std; #define ll long long #define itn int #define lowbit(x) x&(-x) const int N=2e5+5; int n,c[N]; queue<int >q[30]; char s[N]; ll ans=0; void updata(int i,int v) { while(i<=n) { c[i]+=v; i+=lowbit(i); } } int getsum(int i) { int s=0; while(i) { s+=c[i]; i-=lowbit(i); } return s; } int main() { scanf("%d%s",&n,s+1); for(int i=1; i<=n; i++) { q[s[i]-'a'].push(i); updata(i,1); } for(int i=n; i; i--) { int p=q[s[i]-'a'].front(); q[s[i]-'a'].pop(); ans+=getsum(p)-1; updata(p,-1); } cout<<ans<<endl; return 0; }View Code