A题B题,水的不行,跳过。
C题,每一个人都肯定消灭掉后面的一个字母不同的人,那么用队列保存两个阵营的人的位置,每一轮以后都让位置加上n即可。具体见代码:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <queue> 5 using namespace std; 6 const int N = 200000 + 5; 7 8 char s[N]; 9 10 int main() 11 { 12 int n; 13 scanf("%d%s",&n,s+1); 14 queue<int> qD,qR; 15 for(int i=1;i<=n;i++) if(s[i] == 'D') qD.push(i); else qR.push(i); 16 while(!qD.empty() && !qR.empty()) 17 { 18 int x = qD.front(); qD.pop(); 19 int y = qR.front(); qR.pop(); 20 if(x < y) qD.push(x + n); 21 else qR.push(y + n); 22 } 23 if(qD.empty()) puts("R"); 24 else puts("D"); 25 return 0; 26 }
D题,维护一个set,里面用来保存pair<mx[i],i>,mx[i]表示i这个人喊出的最高的价格,lis[i]保存i这个人喊出的所有的价格,那么每次要删除i这个人,在set里面删除,然后看set的size():如果是0,那么输出0 0;如果是1,那么肯定只有一个人了,在lis[i]里面找他的最低的价格即可;如果大于等于2,那么,价格较大的两个人拿出来,更大的那个人的最小价格就是答案了。感觉复杂度是qnlogn,但是没超时,很奇怪- -。具体见代码:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <queue> 5 #include <set> 6 #include <vector> 7 using namespace std; 8 const int N = 200000 + 5; 9 typedef pair<int,int> pii; 10 11 int n,q; 12 set<pii> pos; 13 vector<int> lis[N]; 14 bool vis[N]; 15 int mx[N]; 16 int del[N]; 17 18 int main() 19 { 20 scanf("%d",&n); 21 for(int i=1;i<=n;i++) 22 { 23 int a,b;scanf("%d%d",&a,&b); 24 vis[a] = 1; 25 lis[a].push_back(b); 26 mx[a] = max(mx[a], b); 27 } 28 for(int i=1;i<=n;i++) if(vis[i]) pos.insert(pii(mx[i], i)); 29 scanf("%d",&q); 30 while(q--) 31 { 32 int L;scanf("%d",&L); 33 for(int i=1;i<=L;i++) 34 { 35 scanf("%d",del+i); 36 if(pos.find(pii(mx[del[i]], del[i])) != pos.end()) 37 { 38 pos.erase(pii(mx[del[i]], del[i])); 39 } 40 } 41 if(pos.size() == 0) printf("0 0 "); 42 else if(pos.size() == 1) printf("%d %d ",pos.begin()->second, lis[pos.begin()->second][0]); 43 else 44 { 45 set<pii>::iterator it = pos.end(), it2 = pos.end(); 46 it--; it--; it2--; 47 int a = it->second, b = it2->second; 48 int temp = it->first; 49 /*int L = 0, R = lis[b].size()-1; 50 int ans = -1; 51 while(L <= R) 52 { 53 int mid = L + R >> 1; 54 if(lis[b][mid] > temp) {ans = lis[b][mid]; R = mid - 1;} 55 else L = mid + 1; 56 }*/ 57 int t = lower_bound(lis[b].begin(), lis[b].end(), temp) - lis[b].begin(); 58 int ans = lis[b][t]; 59 printf("%d %d ",b,ans); 60 } 61 for(int i=1;i<=L;i++) if(vis[del[i]]) pos.insert(pii(mx[del[i]], del[i])); 62 } 63 return 0; 64 }
E题,好难- -。见这个人的博客:http://www.cnblogs.com/MashiroSky/p/6246624.html。最后的y还不是理解的很透彻。顺便,那个人的代码用c++11交WA第一组,用14交可过。我自己模仿写的代码,都不行。话说本机调试答案和CF上答案不同是什么意思。。代码如下:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <queue> 5 #include <set> 6 #include <vector> 7 using namespace std; 8 const int N = 100000 + 5; 9 typedef pair<int,int> pii; 10 typedef long long ll; 11 typedef long double ld; 12 13 ll c[N],s[N]; 14 int n; 15 int a[N]; 16 ld ans; 17 18 int lowbit(int x) {return x&-x;} 19 void add(ll *c,int x,ll val) {for(int i=x;i<=n;i+=lowbit(i)) c[i]+=val;} 20 ll query(ll *c,int x) 21 { 22 ll ans = 0; 23 for(int i=x;i;i-=lowbit(i)) ans += c[i]; 24 return ans; 25 } 26 27 void solve1() // 区间包含 28 { 29 ld Q = 0; 30 for(int i=1;i<=n;i++) Q += (ld)(i*(n-i)*(n-i+1))/2/n/(n+1); 31 ans += Q; 32 } 33 void solve2() // 区间不包含 34 { 35 ld Q = 0; 36 for (int i=n;i>=1;i--) 37 { 38 ll x = query(c,a[i]-1); 39 Q -= (ld)(x*((2*i+2*n*i)-(n*n+n)))/n/(n+1); 40 Q += (ld)(2*i)/n/(n+1)*query(s,a[i]-1); 41 add(c,a[i],1); 42 add(s,a[i],i); 43 } 44 ans += Q; 45 } 46 47 int main() 48 { 49 scanf("%d",&n); 50 for(int i=1;i<=n;i++) scanf("%d",a+i); 51 solve1(); 52 solve2(); 53 printf("%.20lf ",ans); 54 return 0; 55 }