codeforces Round #365 Div.2
A. Mishka and Game
两个人玩n把扔骰子,点数大的赢,谁赢得多输出谁的名字,平局输出不可思议的友谊(这都是什么蜜汁输出。。
1 #include <cctype> 2 #include <cstring> 3 #include <cstdlib> 4 #include <vector> 5 #include <math.h> 6 #include <algorithm> 7 #include <iostream> 8 using namespace std; 9 typedef long long LL; 10 const int maxn = 2e5+5; 11 inline int read() { 12 int x=0; 13 int f=1, hhh=getchar(); 14 while(!isdigit(hhh)) { 15 if(hhh=='-') 16 f=-1; 17 hhh=getchar(); 18 } 19 while(isdigit(hhh)) { 20 x=x*10+hhh-'0'; 21 hhh=getchar(); 22 } 23 return x*f; 24 } 25 int n,x,y; 26 int main() { 27 n=read(); 28 int c1=0,c2=0; 29 for (int i=0; i<n; i++) { 30 x=read();y=read(); 31 c1 += x > y; c2 += x < y; 32 } 33 if (c1 > c2) { 34 puts("Mishka"); 35 } else if (c1 == c2) { 36 puts("Friendship is magic!^^"); 37 } else { 38 puts("Chris"); 39 } 40 return 0; 41 }
B. Mishka and trip
n个城市,其中有k个中心城市。每个城市都有一个权值c ,每个城市到编号相邻的两个城市有路,中心城市到任意城市都有路.任意两个城市间最多有一条路。每条边的权值为相邻两个城市的权值的乘积。求所有边的权值的和。
成串的路径权值和很好解决,对每个中心城市单独来说,道路权值和为c[i]*(sum-c[i]),然后因为多算了中心城市之间的路,所以要记一个s2记录已经访问的中心城市权值和,单独来减,最后还要特殊处理两个中心城市编号相邻的情况。。我好像做麻烦了,手推了一万年= =晚上回来再看有没有简易解法。。
1 #include <cstdio> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdlib> 5 #include <vector> 6 #include <math.h> 7 #include <algorithm> 8 #include <iostream> 9 using namespace std; 10 typedef long long LL; 11 const int maxn = 2e5+5; 12 inline int read() { 13 int x=0; 14 int f=1, hhh=getchar(); 15 while(!isdigit(hhh)) { 16 if(hhh=='-') 17 f=-1; 18 hhh=getchar(); 19 } 20 while(isdigit(hhh)) { 21 x=x*10+hhh-'0'; 22 hhh=getchar(); 23 } 24 return x*f; 25 } 26 int n,k,c[maxn],f[maxn],t; 27 int main() { 28 n=read();k=read(); 29 LL sum = 0, ans = 0, s2 = 0; 30 for (int i=1; i<=n; i++) { 31 c[i]=read();sum+=c[i]; 32 } 33 for (int i=0; i<k; i++) { 34 t=read();f[t]=1; 35 } 36 c[0] = c[n], c[n+1] = c[1]; 37 f[0] = f[n], f[n+1] = f[1]; 38 for (int i=1; i<=n; i++) { 39 ans += c[i] * c[i+1]; 40 } 41 for (int i=1; i<=n; i++) { 42 if (f[i]) { 43 ans += c[i] * (sum - c[i]) - c[i] * c[i-1] - c[i] * c[i+1]; 44 ans -= s2 * c[i]; 45 s2 += c[i]; 46 if (f[i+1]) { 47 ans += c[i] * c[i+1]; 48 } 49 } 50 } 51 cout<<ans<<endl; 52 return 0; 53 }
C. Chris and Road
一个人要从0 0到0 w,只能沿y轴走,行走速度最大是u,然后有一辆车,是一个多边形,向x轴负方向匀速运动,问人不被车撞到的情况下,最快多久能过马路。
分类讨论,明显人要么在车过来之前走过去,要么等车过去了再过去。后者二分等待时间就可以了。
1 #include <cstdio> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdlib> 5 #include <vector> 6 #include <map> 7 #include <math.h> 8 #include <algorithm> 9 #include <iostream> 10 using namespace std; 11 #define lowbit(x) (x&-x) 12 typedef long long LL; 13 const int maxn = 2e6+5; 14 const double eps = 1e-8; 15 inline int read() { 16 int x=0; 17 int f=1, hhh=getchar(); 18 while(!isdigit(hhh)) { 19 if(hhh=='-') 20 f=-1; 21 hhh=getchar(); 22 } 23 while(isdigit(hhh)) { 24 x=x*10+hhh-'0'; 25 hhh=getchar(); 26 } 27 return x*f; 28 } 29 int e(double x) { 30 if (x > eps) { 31 return 1; 32 } 33 if (x < -eps) { 34 return -1; 35 } 36 return 0; 37 } 38 struct point { 39 double x,y; 40 void read() { 41 scanf("%lf%lf",&x,&y); 42 } 43 } p[maxn]; 44 int n,w,v,u; 45 bool safe() { 46 for (int i=0; i<n; i++) { 47 if (e(u*p[i].x-v*p[i].y) < 0) { 48 return 0; 49 } 50 } 51 return 1; 52 } 53 bool check(double t) { 54 for (int i=0; i<n; i++) { 55 if (e(u*p[i].x-v*p[i].y-u*v*t)>0) { 56 return 0; 57 } 58 } 59 return 1; 60 } 61 int main() { 62 n=read();w=read();v=read();u=read(); 63 for (int i=0; i<n; i++) { 64 p[i].read(); 65 } 66 if (safe()) { 67 printf("%f\n",1.0*w/u); 68 return 0; 69 } 70 double l=0, r=2e9; 71 while (e(r-l) > 0) { 72 double m = (l+r)/2; 73 if (check(m)) { 74 r=m; 75 } else { 76 l=m; 77 } 78 } 79 printf("%f\n",1.0*w/u+r); 80 return 0; 81 }
D. Mishka and Interesting sum
给你n个数,m个询问,求区间出现次数为偶数次的数的异或和
奇数次异或和大家都会做,直接异或就行,那么要求偶数次的话,再异或一次每个不重复的数的异或和就好了。
转化成这样是不是很眼熟?/*不眼熟的话请恶补线段树专题w*/树状数组和线段树都可以做,把询问离线出来,按区间右端点升序排序,对每一个数记录当前值的位置,然后不断的向右更新:右边和左边有相同值的话,下一个区间一定能把右边的值算进去,左边就不需要了。
1 #include <cstdio> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdlib> 5 #include <vector> 6 #include <map> 7 #include <math.h> 8 #include <algorithm> 9 #include <iostream> 10 using namespace std; 11 #define lowbit(x) (x&-x) 12 typedef long long LL; 13 const int maxn = 2e6+5; 14 inline int read() { 15 int x=0; 16 int f=1, hhh=getchar(); 17 while(!isdigit(hhh)) { 18 if(hhh=='-') 19 f=-1; 20 hhh=getchar(); 21 } 22 while(isdigit(hhh)) { 23 x=x*10+hhh-'0'; 24 hhh=getchar(); 25 } 26 return x*f; 27 } 28 struct node { 29 int l,r,i,ans; 30 } q[maxn]; 31 bool cmpr(node a, node b) { 32 return a.r<b.r; 33 } 34 bool cmpi(node a, node b) { 35 return a.i<b.i; 36 } 37 int n,a[maxn],m,f[maxn],no[maxn],b[maxn]; 38 map<int,int> mp; 39 void add(int x,int y) { 40 for (; x<=n; x+=lowbit(x)) 41 f[x]^=y; 42 } 43 int query(int x) { 44 int ret=0; 45 for (; x; x-=lowbit(x)) 46 ret^=f[x]; 47 return ret; 48 } 49 int main() { 50 n=read(); 51 for (int i=1; i<=n; i++) { 52 a[i]=read(); no[i] = no[i-1]^a[i]; 53 b[i]=mp[a[i]]; mp[a[i]] = i; 54 } 55 m=read(); 56 for (int i=1; i<=m; i++) { 57 q[i].l=read();q[i].r=read();q[i].i=i; 58 } 59 sort(q+1, q+m+1, cmpr); 60 for (int i=1,k=1; i<=m; i++) { 61 for (; k<=q[i].r; k++) { 62 if (b[k]) add(b[k], a[k]); 63 add(k, a[k]); 64 } 65 q[i].ans = no[q[i].r]^no[q[i].l-1]^query(q[i].r)^query(q[i].l-1); 66 } 67 sort(q+1, q+m+1, cmpi); 68 for (int i=1; i<=m; i++) 69 printf("%d\n", q[i].ans); 70 return 0; 71 }
E还没太看懂题……嗯先挂着……我一定会回来补的就是这样XD