A题B题,水的不行,跳过。
C题,每一个人都肯定消灭掉后面的一个字母不同的人,那么用队列保存两个阵营的人的位置,每一轮以后都让位置加上n即可。具体见代码:
1 #include2 #include 3 #include 4 #include 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 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 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 const int N = 200000 + 5; 9 typedef pair pii;10 11 int n,q;12 set pos;13 vector 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\n");42 else if(pos.size() == 1) printf("%d %d\n",pos.begin()->second, lis[pos.begin()->second][0]);43 else44 {45 set ::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\n",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题,好难- -。见这个人的博客:。最后的y还不是理解的很透彻。顺便,那个人的代码用c++11交WA第一组,用14交可过。我自己模仿写的代码,都不行。话说本机调试答案和CF上答案不同是什么意思。。代码如下:
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 const int N = 100000 + 5; 9 typedef pair 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\n",ans);54 return 0;55 }