Codeforces Round #285 (Div. 2) ABCD

A题

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6
 7 using namespace std;
 8
 9 #define LL long long
10 #define eps 1e-8
11 #define inf 0x3f3f3f3f
12 #define mnx 100010
13
14 int main(){
15     int a, b, c, d;
16     scanf( "%d%d%d%d", &a, &b, &c, &d );
17     int a1 = max( 3 * a / 10, a - a / 250 * c );
18     int a2 = max( 3 * b / 10, b - b / 250 * d );
19     if( a1 > a2 ) puts( "Misha" );
20     else if( a1 == a2 ) puts( "Tie" );
21     else puts( "Vasya" );
22     return 0;
23 }

B题

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6
 7 using namespace std;
 8
 9 #define LL long long
10 #define eps 1e-8
11 #define inf 0x3f3f3f3f
12 #define mnx 1010
13
14 char s[mnx][mnx], ch[mnx][mnx];
15 int main(){
16     int n, m = 0;
17     scanf( "%d", &n );
18     for( int i = 0; i < n; ++i ){
19         cin >> s[m] >> ch[m];
20         bool ok = 1;
21         int j;
22         for( j = 0; j < m; ++j ){
23             if( strcmp( ch[j], s[m] ) == 0 ){ ok = 0; break; }
24         }
25         if( ok ) m++;
26         else strcpy( ch[j], ch[m] );
27     }
28     cout << m << endl;
29     for( int i = 0; i < m; ++i ){
30         cout << s[i] << " " << ch[i] << endl;
31     }
32 }

C题 傻逼了,想错了。。后来发现把相连的边的数量当做入度,把全部node都塞进优先队列里,每次弹出度数最小的点u。如果访问过或者度数为0,就continue;否则就找到 v = u.val ^ x[u],给v所在节点的入度减1,x[v] ^= u,再把v塞进队列里,同时标记u已经访问过。记录边(u,v)我直接就用了vector

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8
 9 using namespace std;
10
11 #define LL long long
12 #define eps 1e-8
13 #define inf 0x3f3f3f3f
14 #define mnx 300100
15
16 vector<int> g[mnx];
17 struct node{
18     int in, val, id;
19     bool operator < ( const node &b ) const {
20         return in > b.in;
21     }
22 }c[mnx];
23 int x[mnx];
24 bool vis[mnx];
25 int main(){
26     int n, m = 0;
27     scanf( "%d", &n );
28     priority_queue<node> q;
29     for( int i = 0; i < n; ++i ){
30         scanf( "%d %d", &c[i].in, &c[i].val );
31         c[i].id = i;
32         q.push( c[i] );
33     }
34     while( !q.empty() ){
35         node kk = q.top(); q.pop();
36         int u = kk.id;
37         if( vis[u] ) continue;
38         vis[u] = 1;
39         if( kk.in == 0 ) continue;
40         int v = kk.val ^ x[u];
41         x[v] ^= u;
42         c[v].in--;
43         q.push( c[v] );
44         g[u].push_back( v );
45         m++;
46     }
47     cout << m << endl;
48     for( int i = 0; i < n; ++i ){
49         int k = g[i].size();
50         for( int j = 0; j < k; ++j )
51             cout << i << " " << g[i][j] << endl;
52     }
53     return 0;
54 }

D题 看到别人的题解说的 康托展开。果然知识面不够丰富。

如我想知道321是{1,2,3}中第几个小的数可以这样考虑 :

第一位是3,当第一位的数小于3时,那排列数小于321 如 123、 213 ,小于3的数有1、2 。所以有2*2!个。再看小于第二位2的:小于2的数只有一个就是1 ,所以有1*1!=1 所以小于321的{1,2,3}排列数有2*2!+1*1!=5个。所以321是第6个小的数。 2*2!+1*1!+0*0!就是康托展开。

一个全排列 ,可以看成a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[2]*1!+a[1]*0!, 那么其实只要处理出每一项的系数,然后把两个序列的系数加起来,然后进行进位操作,就可以求出答案的每一项的系数。求系数实际上就是求后面有多少个数是小于这个数的。这个过程要利用树状数组来维护。

求出答案的系数后,再二分找答案(开始的时候一直都写不对这个二分,后来看了题解的二分,发现自己有智商捉急了)。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8
 9 using namespace std;
10
11 #define LL long long
12 #define eps 1e-8
13 #define inf 0x3f3f3f3f
14 #define mnx 300100
15
16 int p[mnx], q[mnx], bit[mnx], n;
17 int sum( int x ){
18     int ret = 0;
19     while( x > 0 ){
20         ret += bit[x];
21         x -= x & -x;
22     }
23     return ret;
24 }
25 void add( int i, int x ){
26     while( i <= n ){
27         bit[i] += x;
28         i += i & -i;
29     }
30 }
31 int main(){
32     scanf( "%d", &n );
33     for( int i = 1; i <= n; ++i ){
34         scanf( "%d", &p[i] );
35         int tmp = sum( p[i] );
36         q[i] += p[i] - tmp;
37         add( p[i] + 1, 1 );
38     }
39     memset( bit, 0, sizeof( bit ) );
40     for( int i = 1; i <= n; ++i ){
41         scanf( "%d", &p[i] );
42         int tmp = sum( p[i] );
43         q[i] += p[i] - tmp;
44         add( p[i] + 1, 1 );
45     }
46     for( int i = n; i > 0; --i )
47         if( q[i] >= ( n - i + 1) ){
48             q[i-1] += q[i] / ( n - i + 1 );
49             q[i] %= ( n - i + 1);
50         }
51     memset( bit, 0, sizeof( bit ) );
52     for( int i = 1; i <= n; ++i ) add( i, 1 );
53     for( int i = 1; i <= n; ++i ){
54         int l = 1, r = n;
55         while( l < r ){
56             int mid = ( l+r ) >> 1;        设q[i] = 2, mid = 4, 数字2已经用了。
57             int tmp = sum( mid );          假设4还没有用,这时tmp = 3, tmp - 1 == 2 == q[i], 4应该是右端点
58             if( tmp - 1 < q[i] )           假设4已经用了,这时tmp = 2, tmp - 1 == 1 < q[i], 此时5应该是左端点
59                 l = mid + 1;
60             else r = mid;
61         }
62         cout << l - 1 << " ";
63         add( l, -1 );
64     }
65     return 0;
66 }

时间: 2024-10-16 09:00:02

Codeforces Round #285 (Div. 2) ABCD的相关文章

字符串处理 Codeforces Round #285 (Div. 2) B. Misha and Changing Handles

题目传送门 1 /* 2 题意:给出一系列名字变化,问最后初始的名字变成了什么 3 字符串处理:每一次输入到之前的找相印的名字,若没有,则是初始的,pos[m] 数组记录初始位置 4 在每一次更新时都把初始pos加上去,那么就保证更新了初始的名字,这也是唯一要思考的地方了:) 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <cstring> 9 #include <algorithm> 1

图论/位运算 Codeforces Round #285 (Div. 2) C. Misha and Forest

题目传送门 1 /* 2 题意:给出无向无环图,每一个点的度数和相邻点的异或和(a^b^c^....) 3 图论/位运算:其实这题很简单.类似拓扑排序,先把度数为1的先入对,每一次少一个度数 4 关键在于更新异或和,精髓:a ^ b = c -> a ^ c = b, b ^ c = a; 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <cmath> 9 #include <algorith

Codeforces Round #258 (Div. 2)[ABCD]

Codeforces Round #258 (Div. 2)[ABCD] ACM 题目地址:Codeforces Round #258 (Div. 2) A - Game With Sticks 题意: Akshat and Malvika两人玩一个游戏,横竖n,m根木棒排成#型,每次取走一个交点,交点相关的横竖两条木棒要去掉,Akshat先手,给出n,m问谁赢. 分析: 水题,很明显不管拿掉哪个点剩下的都是(n-1,m-1),最后状态是(0,x)或(x,0),也就是拿了min(n,m)-1次,

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #354 (Div. 2) ABCD

Codeforces Round #354 (Div. 2) Problems # Name     A Nicholas and Permutation standard input/output 1 s, 256 MB    x3384 B Pyramid of Glasses standard input/output 1 s, 256 MB    x1462 C Vasya and String standard input/output 1 s, 256 MB    x1393 D T

Codeforces Round #Pi (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/567 听说Round #Pi的意思是Round #314... A. Lineland Mail time limit per test:3 seconds memory limit per test:256 megabytes All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with it

Codeforces Round #250 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/433 A. Kitahara Haruki's Gift time limit per test:1 second memory limit per test:256 megabytes Kitahara Haruki has bought n apples for Touma Kazusa and Ogiso Setsuna. Now he wants to divide all the apples between th

Codeforces Round #143 (Div. 2) (ABCD 思维场)

题目连链接:http://codeforces.com/contest/231 A. Team time limit per test:2 seconds memory limit per test:256 megabytes One day three best friends Petya, Vasya and Tonya decided to form a team and take part in programming contests. Participants are usually

Codeforces Round #249 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/435 A. Queue on Bus Stop time limit per test:1 second memory limit per test:256 megabytes It's that time of the year when the Russians flood their countryside summer cottages (dachas) and the bus stop has a lot of p