A 小甜甜
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string> 10 #include <string.h> 11 #include <stdlib.h> 12 #include <time.h> 13 #include <climits> 14 15 using namespace std; 16 17 const int maxN=5e6+7; 18 19 unsigned int sta[maxN]; 20 int to[maxN]; 21 int top=0; 22 23 int n,p,q,m; 24 unsigned int SA,SB,SC; 25 long long ans=0; 26 27 unsigned int rng61(){ 28 SA^=SA<<16; 29 SA^=SA>>5; 30 SA^=SA<<1; 31 unsigned int t=SA; 32 SA=SB; 33 SB=SC; 34 SC^=t^SA; 35 return SC; 36 } 37 38 void PUSH(unsigned int x,int i){ 39 //cerr<<"PUSH"<<x<<endl; 40 top++; 41 sta[top]=x; 42 43 if (x>sta[to[top-1]]) to[top]=top; 44 else to[top]=to[top-1]; 45 46 ans=ans^(1LL*sta[to[top]]*i); 47 } 48 49 void POP(int i){ 50 //cerr<<"POP"<<endl; 51 if (top==0) return; 52 top--; 53 if (top==0) return; 54 55 ans=ans^(1LL*sta[to[top]]*i); 56 } 57 58 void gen(){ 59 scanf("%d%d%d%d%u%u%u",&n,&p,&q,&m,&SA,&SB,&SC); 60 ans=top=0; 61 62 for (int i=1;i<=n;i++) { 63 if (rng61()%(p+q)<p) PUSH(rng61()%m+1,i); 64 else POP(i); 65 } 66 67 printf("%lld ",ans); 68 } 69 70 71 int main(){ 72 int T; 73 scanf("%d",&T); 74 int kcase=0; 75 while (T--){ 76 printf("Case #%d: ",++kcase); 77 gen(); 78 } 79 return 0; 80 }
B 小洛洛
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <cstdlib> 6 #include <cmath> 7 using namespace std; 8 9 typedef long long ll; 10 11 const int N = 55; 12 struct P_ { 13 int x, y; 14 P_ operator-(const P_ &r) const { 15 return (P_) { x - r.x, y - r.y }; 16 } 17 double norm() const { 18 return hypot((double)x, (double)y); 19 } 20 double operator*(const P_ &r) const { 21 return (double)x * r.x + (double)y * r.y; 22 } 23 } pts[N]; 24 25 int main() { 26 int T; 27 scanf("%d", &T); 28 for(int it = 1; it <= T; ++it) { 29 int n; 30 scanf("%d", &n); 31 for(int i = 0; i < n; ++i) { 32 scanf("%d%d", &pts[i].x, &pts[i].y); 33 } 34 pts[n] = pts[0]; 35 pts[n + 1] = pts[1]; 36 P_ p0; 37 scanf("%d%d", &p0.x, &p0.y); 38 double ans = 0.0; 39 for(int i = 0; i < n; ++i) { 40 double r = (p0 - pts[i + 1]).norm(); 41 P_ a = pts[i + 1] - pts[i], 42 b = pts[i + 2] - pts[i + 1]; 43 double th = acos(a * b / (a.norm() * b.norm())); 44 ans += r * th; 45 } 46 printf("Case #%d: %.3f ", it, ans); 47 } 48 return 0; 49 }
C BPM136
计算出偏移量即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdlib> 6 #include<algorithm> 7 8 using namespace std; 9 10 typedef long long ll; 11 12 const int N = 100; 13 14 char s1[N]; 15 char s2[N]; 16 int n,m; 17 18 char s[N]; 19 20 int main() { 21 int T,kcas=0; 22 scanf("%d",&T); 23 while(T--) { 24 scanf("%d%d",&n,&m); 25 scanf("%s%s%s",s1,s2,s); 26 int ca=s1[0]-s2[0]; 27 28 printf("Case #%d: ",++kcas); 29 for(int i=0;i<m;i++) putchar((s[i]-'A'+(ca)+26)%26+'A'); 30 puts(""); 31 } 32 return 0; 33 }
D 小洛洛
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <cstdlib> 6 using namespace std; 7 8 int main() { 9 int T; 10 scanf("%d", &T); 11 for(int it = 1; it <= T; ++it) { 12 int n, m; 13 scanf("%d%d", &n, &m); 14 double ans1 = (n == 1 ? 1 : 0.5); 15 double ans2 = (m + 1.0) / (2.0 * m); 16 printf("Case #%d: %.6f %.6f ", it, ans1, ans2); 17 } 18 return 0; 19 }
E 小洛洛
模拟即可,一脸蛋疼
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <cstdlib> 6 using namespace std; 7 8 const int N = 500003; 9 struct T_ { 10 int n; 11 int v[3]; 12 T_ *ch[4]; 13 } ss[N], *sp; 14 15 void dfs_(T_ *c) { 16 if(!c) return; 17 for(int i = 0; i < c->n; ++i) { 18 if(i != 0) 19 putchar(' '); 20 printf("%d", c->v[i]); 21 } 22 putchar(' '); 23 for(int i = 0; i <= c->n; ++i) 24 dfs_(c->ch[i]); 25 } 26 27 28 void fuxk_rt_(T_ *&c) { 29 if(c->n == 3) { 30 T_ *c2 = sp++, *nc = sp++; 31 *c2 = (T_){ 1, { c->v[2] }, { c->ch[2], c->ch[3] } }; 32 *nc = (T_){ 1, { c->v[1] }, { c, c2 } }; 33 c->n = 1; 34 c = nc; 35 } 36 } 37 38 bool insert_(T_ *&c, int val) { 39 if(!c) { 40 *(c = sp++) = (T_) { 1, { val }, { NULL, NULL } }; 41 return true; 42 } else if(c->n == 3) 43 return false; 44 else if(c->ch[0]) { 45 rerun: 46 int i = 0; 47 while(i < c->n && c->v[i] < val) ++i; 48 49 T_ *sub = c->ch[i]; 50 if(!insert_(sub, val)) { 51 for(int j = c->n; j > i; --j) 52 c->v[j] = c->v[j - 1]; 53 for(int j = ++c->n; j > i; --j) 54 c->ch[j] = c->ch[j - 1]; 55 56 T_ *c2 = sp++; 57 *c2 = (T_){ 1, { sub->v[2] }, { sub->ch[2], sub->ch[3] } }; 58 sub->n = 1; 59 c->v[i] = sub->v[1]; 60 c->ch[i] = c2; 61 swap(c->ch[i], c->ch[i + 1]); 62 goto rerun; 63 } 64 return true; 65 } else { 66 int i = 0; 67 while(i < c->n && c->v[i] < val) ++i; 68 for(int j = c->n; j > i; --j) 69 c->v[j] = c->v[j - 1]; 70 ++c->n; 71 c->ch[c->n] = NULL; 72 c->v[i] = val; 73 return true; 74 } 75 } 76 77 int main() { 78 int T; 79 scanf("%d", &T); 80 for(int it = 1; it <= T; ++it) { 81 int n; 82 scanf("%d", &n); 83 84 sp = ss; 85 T_ *rt = NULL; 86 for(int i = 0; i < n; ++i) { 87 int x; 88 scanf("%d", &x); 89 while(!insert_(rt, x)) 90 fuxk_rt_(rt); 91 } 92 printf("Case #%d: ", it); 93 dfs_(rt); 94 } 95 return 0; 96 }
F BPM136
考虑floyed,每次加进点更新就好了
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdlib> 6 #include<algorithm> 7 8 using namespace std; 9 #define int long long 10 11 const int N = 205; 12 const int M = 20005; 13 14 int d[N][N]; 15 int f[N][N]; 16 int a[N]; 17 int n,m; 18 19 struct ques { 20 int x,y,id; 21 int w; 22 int ans; 23 }q[M]; 24 25 bool cmp_id(ques a,ques b) { 26 return a.id<b.id; 27 } 28 bool cmp_w(ques a,ques b) { 29 return a.w>b.w; 30 } 31 32 struct node { 33 int x; 34 int w; 35 }p[N]; 36 37 bool cmp_node_w(node a,node b) { 38 return a.w<b.w; 39 } 40 41 bool vis[N]; 42 43 main() { 44 int T,kcas=0; 45 scanf("%lld",&T); 46 while(T--) { 47 scanf("%lld%lld",&n,&m); 48 for(int i=1;i<=n;i++) { 49 scanf("%lld",&a[i]); 50 p[i].w=a[i]; 51 p[i].x=i; 52 } 53 memset(vis,0,sizeof(vis)); 54 for(int i=1;i<=n;i++) { 55 for(int j=1;j<=n;j++) { 56 scanf("%lld",&d[i][j]); 57 f[i][j]=d[i][j]; 58 } 59 } 60 61 for(int i=1;i<=m;i++) { 62 scanf("%lld%lld%lld",&q[i].x,&q[i].y,&q[i].w); 63 q[i].id=i; 64 } 65 66 sort(q+1,q+m+1,cmp_w); 67 sort(p+1,p+n+1,cmp_node_w); 68 69 int l=1; 70 for(int o=m;o>=1;o--) { 71 while(l <= n && p[l].w<=q[o].w) { 72 int k=p[l].x; 73 vis[k]=1; 74 for(int i=1;i<=n;i++) { 75 for(int j=1;j<=n;j++) { 76 if(f[i][k]+f[k][j]<f[i][j]) { 77 f[i][j]=f[i][k]+f[k][j]; 78 } 79 } 80 } 81 l++; 82 } 83 84 q[o].ans=f[q[o].x][q[o].y]; 85 } 86 sort(q+1,q+m+1,cmp_id); 87 printf("Case #%lld: ",++kcas); 88 for(int i=1;i<=m;i++) { 89 printf("%lld ",q[i].ans); 90 } 91 } 92 return 0; 93 }
G BPM136
树形DP,fi,j表示在i的子树中选j个,在最优情况下的贡献是多少
转移min(size,m)之后复杂度为O(nk)
whx的证明:找个割出来,割以上子树大小大于k,割以下子树大小小于k。然后上面最多n/k个合并,下面每对在割上共一个点的点对被算一次,每人最多和k个被算
每条边的贡献为p(k-p)
1 /* *********************************************** 2 Author :BPM136 3 Created Time :2018/7/17 21:39:31 4 File Name :G.cpp 5 ************************************************ */ 6 7 #include<iostream> 8 #include<cstdio> 9 #include<algorithm> 10 #include<cstdlib> 11 #include<cmath> 12 #include<cstring> 13 #include<vector> 14 using namespace std; 15 16 typedef long long ll; 17 18 const int N = 100005; 19 const int M = 105; 20 const ll inf = 1e17; 21 22 struct edge { 23 int y,w,next; 24 }e[N<<1]; 25 int last[N],ne; 26 27 ll f[N][M]; 28 ll sum[N][M]; 29 int siz[N]; 30 int n,m; 31 32 void add(int x,int y,int w) { 33 e[++ne].y=y; e[ne].w=w; e[ne].next=last[x]; last[x]=ne; 34 } 35 void add2(int x,int y,int w) { 36 add(x,y,w); 37 add(y,x,w); 38 } 39 40 ll cur[M]; 41 ll sum_cur[M]; 42 int du[N]; 43 void dfs(int x,int pre) { 44 siz[x]=0; 45 f[x][0]=0; for(int i=1;i<=m;i++) f[x][i]=inf; 46 sum[x][0]=0; for(int i=1;i<=m;i++) sum[x][i]=inf; 47 int flag=1; 48 for(int i=last[x];i!=0;i=e[i].next) { 49 int y=e[i].y; 50 if(y==pre) continue; 51 flag=0; 52 dfs(y,x); 53 54 for(int p=0;p<=m;p++) cur[p]=f[x][p],f[x][p]=inf; 55 for(int p=0;p<=m;p++) sum_cur[p]=sum[x][p],sum[x][p]=inf; 56 int bound0=min(m,siz[x]); 57 int bound1=min(m,siz[y]); 58 for(int p=0;p<=bound0;p++) { 59 for(int q=0;q<=bound1 && p+q<=m;q++) { 60 if(f[x][p+q]>cur[p]+f[y][q]+(ll)e[i].w*(m-q)*q) { 61 f[x][p+q]=cur[p]+f[y][q]+(ll)e[i].w*(m-q)*q; 62 } 63 } 64 } 65 siz[x]+=siz[y]; 66 } 67 if(siz[x]==0 && flag==1) { 68 siz[x]=1; 69 f[x][1]=0; 70 sum[x][1]=0; 71 } 72 } 73 74 int main() { 75 int T,kcas=0; 76 scanf("%d",&T); 77 while(T--) { 78 scanf("%d%d",&n,&m); 79 memset(last,0,sizeof(last)); 80 memset(du,0,sizeof(du)); 81 ne=0; 82 int tmp; 83 for(int i=1;i<n;i++) { 84 int x,y,w; 85 scanf("%d%d%d",&x,&y,&w); 86 tmp=w; 87 add2(x,y,w); 88 du[x]++; du[y]++; 89 } 90 if(n==2) { 91 if(m==1) printf("Case #%d: 0 ",++kcas); 92 if(m==2) printf("Case #%d: %d ",++kcas,tmp); 93 continue; 94 } 95 96 int root=0; 97 for(int i=1;i<=n;i++) if(du[i]!=1) { 98 root=i; 99 break; 100 } 101 dfs(root,-1); 102 printf("Case #%d: %lld ",++kcas,f[root][m]); 103 } 104 return 0; 105 }
H 小甜甜+BPM136
考虑如果需要zi次才能打到对手,那么微扰法,只需要ATKj * Zi < ATKi * Zj 就是好的,于是sort即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<cstdlib> 7 8 using namespace std; 9 10 typedef long long ll; 11 12 const int N = 100005; 13 14 struct node { 15 ll ATK; 16 ll HP; 17 ll Z; 18 ll S; 19 }a[N]; 20 21 bool cmp(node a,node b) { 22 return b.ATK*a.Z<b.Z*a.ATK; 23 } 24 25 int n; 26 27 ll EF(ll a) { 28 ll l=1,r=1e9; 29 ll ret=0; 30 while(l<=r) { 31 ll mid=(l+r)>>1; 32 if(mid*mid+mid-2*a>=0) { 33 ret=mid; 34 r=mid-1; 35 } else l=mid+1; 36 } 37 return ret; 38 } 39 40 int main() { 41 int T,kcas=0; 42 scanf("%d",&T); 43 while(T--) { 44 scanf("%d",&n); 45 for(int i=1;i<=n;i++) { 46 scanf("%lld%lld",&a[i].HP,&a[i].ATK); 47 a[i].Z=EF(a[i].HP); 48 } 49 sort(a+1,a+n+1,cmp); 50 for(int i=1;i<=n;i++) a[i].S=a[i-1].S+a[i].Z; 51 ll ans=0; 52 for(int i=1;i<=n;i++) ans+=a[i].S*a[i].ATK; 53 printf("Case #%d: %lld ",++kcas,ans); 54 } 55 return 0; 56 }
I 待补
J 待补
K 小洛洛
状压暴力check,大力出奇迹
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <cstdlib> 6 #include <map> 7 using namespace std; 8 9 typedef long long ll; 10 11 const int N = 40; 12 int n; 13 ll MOD, w[N], nei[N]; 14 bool tbl[N][N]; 15 16 map<ll, int> mp; 17 18 ll f_(ll rest) { 19 if(!rest) return 1; 20 if(mp.find(rest) == mp.end()) { 21 int i = 0; 22 while(~rest & (1LL << i)) ++i; 23 ll ret = 0; 24 ll cnei = nei[i] & rest; 25 if(~cnei & (1LL << i)) { // not sel 26 ll ws = 1; 27 for(int j = 0; j < n; ++j) 28 if(cnei & (1LL << j)) 29 ws = ws * w[j] % MOD; 30 ret = (ret + ws * f_(rest & ~(1LL << i | cnei))) % MOD; 31 } 32 ret = (ret + w[i] * f_(rest ^ (1LL << i))) % MOD; 33 //printf("<%lld: %lld> ", rest, ret); 34 mp[rest] = ret; 35 } 36 return mp[rest]; 37 } 38 39 bool dfvis[N]; 40 ll dfs_(int c) { 41 ll ret = 1LL << c; 42 for(int i = 0; i < n; ++i) 43 if(!dfvis[i] && tbl[c][i]) { 44 dfvis[i] = true; 45 ret |= 1L << i; 46 ret |= dfs_(i); 47 } 48 return ret; 49 } 50 51 int main() { 52 int T; 53 scanf("%d", &T); 54 for(int it = 1; it <= T; ++it) { 55 memset(tbl, 0, sizeof tbl); 56 memset(dfvis, 0, sizeof dfvis); 57 58 int m; 59 scanf("%d%d%lld", &n, &m, &MOD); 60 for(int i = 0; i < n; ++i) 61 scanf("%lld", w + i); 62 for(int i = 0; i < m; ++i) { 63 int a, b; 64 scanf("%d%d", &a, &b); 65 tbl[--a][--b] = true; 66 tbl[b][a] = true; 67 } 68 69 for(int i = 0; i < n; ++i) { 70 nei[i] = 0; 71 for(int j = 0; j < n; ++j) 72 if(i != j && tbl[i][j]) 73 nei[i] |= 1LL << j; 74 } 75 76 ll ans = 1; 77 for(int i = 0; i < n; ++i) 78 if(!dfvis[i]) { 79 ll blk = dfs_(i); 80 mp.clear(); 81 ans = ans * f_(blk) % MOD; 82 } 83 printf("Case #%d: %lld ", it, ans); 84 } 85 return 0; 86 }
L
题意:给一个长度n的数组,求有多少个区间满足区间内元素排序后相邻两个元素的差不超过1,元素可能重复
解法:记max为区间最大值,min区间最小值,cnt为区间中不同数的个数,那么,如果区间满足题中要求,需满足max-min+1-cnt=0。因此,可以从左向右枚举右端点,同时用线段树维护max-min+1-cnt等于0的个数(线段树记录区间最小值及最小值出现的次数)。对于cnt,找到a[R]上次出现的位置,然后这个位置之后到当前点这个区间所有值减一;对于min和max,考虑使用单调栈,减去原来/加上的max/min,再加上/减去新的max/min即可,瞎搞搞就好了。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #include <vector> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <string> 10 #include <string.h> 11 #include <stdlib.h> 12 #include <time.h> 13 #include <climits> 14 #include <stack> 15 16 using namespace std; 17 18 const int maxN=1e5+7; 19 20 ////////// 21 22 #define lson (k<<1) 23 #define rson (k<<1|1) 24 25 int lazy[maxN*4],cnt[maxN*4],MIN[maxN*4]; 26 27 void pushup(int k){ 28 if (MIN[lson]==MIN[rson]) MIN[k]=MIN[lson],cnt[k]=cnt[lson]+cnt[rson]; 29 else if (MIN[lson]<MIN[rson]) MIN[k]=MIN[lson],cnt[k]=cnt[lson]; 30 else MIN[k]=MIN[rson],cnt[k]=cnt[rson]; 31 } 32 33 void pushdown(int k){ 34 if (lazy[k]!=0) { 35 lazy[lson]+=lazy[k]; MIN[lson]+=lazy[k]; 36 lazy[rson]+=lazy[k]; MIN[rson]+=lazy[k]; 37 lazy[k]=0; 38 } 39 } 40 41 void bulidtree(int k,int L,int R){ 42 lazy[k]=0; 43 if (L==R){ 44 cnt[k]=MIN[k]=1; 45 return; 46 } 47 48 int mid=(L+R)>>1; 49 bulidtree(lson,L,mid); 50 bulidtree(rson,mid+1,R); 51 52 pushup(k); 53 } 54 55 void update(int k,int L,int R,int x,int y,int v){ 56 if (x<=L && R<=y){ 57 lazy[k]+=v; 58 MIN[k]+=v; 59 return; 60 } 61 62 pushdown(k); 63 64 int mid=(L+R)>>1; 65 if (x<=mid) update(lson,L,mid,x,y,v); 66 if (y>mid) update(rson,mid+1,R,x,y,v); 67 68 pushup(k); 69 } 70 71 ////////// 72 73 int a[maxN]; 74 int kcase; 75 stack <int> sta1,sta2; 76 map <int,int> rem; 77 78 void work(){ 79 int n; 80 scanf("%d",&n); 81 for (int i=1;i<=n;i++) scanf("%d",a+i); 82 83 long long ans=0; 84 bulidtree(1,1,n); 85 86 while (!sta1.empty()) sta1.pop(); 87 while (!sta2.empty()) sta2.pop(); 88 rem.clear(); 89 90 int k,pre; 91 92 for (int i=1;i<=n;i++) { 93 // max 94 while (!sta1.empty()){ 95 k=sta1.top(); 96 if (a[k]>=a[i]) break; 97 98 sta1.pop(); 99 if (!sta1.empty()) pre=sta1.top()+1; 100 else pre=1; 101 update(1,1,n,pre,k,-a[k]); 102 } 103 if (!sta1.empty()) pre=sta1.top()+1; 104 else pre=1; 105 update(1,1,n,pre,i,a[i]); 106 sta1.push(i); 107 108 // min 109 while (!sta2.empty()) { 110 k=sta2.top(); 111 if (a[k]<=a[i]) break; 112 113 sta2.pop(); 114 if (!sta2.empty()) pre=sta2.top()+1; 115 else pre=1; 116 update(1,1,n,pre,k,a[k]); 117 } 118 if (!sta2.empty()) pre=sta2.top()+1; 119 else pre=1; 120 update(1,1,n,pre,i,-a[i]); 121 sta2.push(i); 122 123 // cnt; 124 if (rem.count(a[i])) pre=rem[a[i]]+1; 125 else pre=1; 126 update(1,1,n,pre,i,-1); 127 rem[a[i]]=i; 128 129 /////// 130 ans+=cnt[1]; 131 } 132 133 printf("Case #%d: %lld ",++kcase,ans); 134 } 135 136 int main(){ 137 int T; 138 scanf("%d",&T); 139 while (T--) work(); 140 return 0; 141 }
M 待补