---------9.14
hdu 5446
中国剩余定理,lucas定理,快速乘法
四处抄的模板拼在一起的----------------
不说了--sad----


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 LL n,m; 9 int k; 10 LL p[15],a[15]; 11 12 13 inline LL mulmod(LL x,LL y,LL mod){ 14 LL ret = 0; 15 if(y < 0) y = (y % mod + mod) % mod; 16 while(y){ 17 if(y & 1) ret = (ret + x) % mod; 18 x = (x + x) % mod; 19 y >>= 1; 20 } 21 return ret; 22 } 23 24 void extend_Euclid(LL a, LL b, LL &x, LL &y){ 25 if(b == 0){ 26 x = 1; 27 y = 0; 28 return; 29 } 30 extend_Euclid(b, a % b, x, y); 31 LL tmp = x; 32 x = y; 33 y = tmp - (a / b) * y; 34 } 35 36 LL CRT(LL a[],LL m[],int n){ 37 LL M = 1; 38 LL ans = 0; 39 for(int i=1; i<=n; i++) 40 M *= m[i]; 41 for(int i=1; i<=n; i++){ 42 LL x,y; 43 LL Mi = M / m[i]; 44 extend_Euclid(Mi, m[i], x, y); 45 // ans = (ans + Mi * x * a[i]) % M; 46 ans = (ans + mulmod(a[i],mulmod(Mi,x,M),M)) % M; 47 } 48 if(ans < 0) ans += M; 49 return ans; 50 } 51 52 LL quick_mod(LL a, LL b,LL p){ 53 LL ans = 1; 54 a %= p; 55 while(b){ 56 if(b & 1){ 57 ans = ans * a % p; 58 b--; 59 } 60 b >>= 1; 61 a = a * a % p; 62 } 63 return ans; 64 } 65 66 LL C(LL n, LL m,LL p){ 67 if(m > n) return 0; 68 if(m > n-m) m = n-m; 69 LL ans = 1; 70 for(int i=1; i<=m; i++) { 71 LL a = (n + i - m) % p; 72 LL b = i % p; 73 ans = mulmod(ans,mulmod(a,quick_mod(b, p-2,p),p),p); 74 } 75 return ans%p; 76 } 77 78 LL Lucas(LL n, LL m,LL p){ 79 if(m == 0) return 1; 80 return mulmod(C(n % p, m % p,p),Lucas(n / p, m / p,p),p); 81 } 82 83 int main(){ 84 int T; 85 scanf("%d", &T); 86 while(T--){ 87 scanf("%I64d%I64d%I64d", &n, &m, &k); 88 for(int i = 1;i <= k;i++) scanf("%I64d",&p[i]); 89 90 for(int i = 1;i <= k;i++) a[i] = Lucas(n,m,p[i]); 91 92 LL res = CRT(a,p,k); 93 printf("%I64d\n",res); 94 } 95 return 0; 96 }
hdu 5437
自己写的时候,还根据每次的时间去模拟,挫爆了,,,觉得应该T的,可是一直re
后来看题解,,才知道应该按人来模拟
然后看了题解之后还wa---
是因为m可以等于0,每次先把允许进来的时间处理成-1就可以了------
滚了-------


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<queue> 6 #include<map> 7 using namespace std; 8 9 const int maxn = 150005; 10 11 struct node1{ 12 char s[305]; 13 int v; 14 int id; 15 friend bool operator < (node1 n1,node1 n2){ 16 if(n1.v != n2.v) return n1.v < n2.v; 17 return n1.id > n2.id; 18 } 19 }a[maxn]; 20 21 struct node2{ 22 int t,p; 23 }b[maxn]; 24 25 int cmp(node2 n1,node2 n2){ 26 return n1.t < n2.t; 27 } 28 29 int n,m,Q; 30 int op[maxn],res[maxn]; 31 32 int main(){ 33 int T; 34 scanf("%d",&T); 35 while(T--){ 36 scanf("%d %d %d",&n,&m,&Q); 37 for(int i = 1;i <= n;i++){ 38 scanf("%s %d",&a[i].s,&a[i].v); 39 a[i].id = i; 40 } 41 42 b[1].t = -1; 43 for(int i = 1;i <= m;i++) scanf("%d %d",&b[i].t,&b[i].p); 44 45 for(int i = 1;i <= Q;i++) scanf("%d",&op[i]); 46 47 memset(res,0,sizeof(res)); 48 sort(b+1,b+m+1,cmp); 49 priority_queue<node1> q; 50 51 int pos = 1,cnt = 0; 52 for(int i = 1;i <= n;i++){ 53 q.push(a[i]); 54 if(i == b[pos].t){ 55 for(int j = 1;j <= b[pos].p && !q.empty();j++){ 56 node1 u = q.top();q.pop(); 57 res[++cnt] = u.id; 58 } 59 pos++; 60 } 61 } 62 while(!q.empty()){ 63 node1 u = q.top();q.pop(); 64 res[++cnt] = u.id; 65 } 66 for(int i = 1;i < Q;i++) printf("%s ",a[res[op[i]]].s); 67 printf("%s\n",a[res[op[Q]]].s); 68 } 69 return 0; 70 }
---------9.15
还是觉得就抄个快速乘法的模板不好,于是滚去找了一下
搜到BC的33场的第二题就是快速幂加快速乘法---
当时根本没有去补题----不知道在干嘛-----
sad-----------
这题先需要推个公式
http://www.cnblogs.com/Opaser/p/4348988.html
然后快速乘法的原理感觉和快速幂差不多
x*y
就是y个x相加的情况
就类比 x ^y,即y个x相乘的情况
然后自己写的时候有两个地方出问题了
第一个是,n = 1的时候,想当然输出1了,但是因为p也可能是1,所以应该输出 n%p
第二个地方是,最后求出答案的时候,还要这样先加上一个mod,再取一次模(话说这样是为了防止负数么--)


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 typedef long long LL; 9 LL n,p; 10 11 12 inline LL mulmod(LL x,LL y,LL mod){ 13 LL ret = 0; 14 if(y < 0) y = (y % mod + mod) % mod; 15 while(y){ 16 if(y & 1) ret = (ret + x) % mod; 17 x = (x + x) % mod; 18 y >>= 1; 19 } 20 return ret; 21 } 22 23 LL quick_mod(LL a, LL b,LL p){ 24 LL ans = 1; 25 a %= p; 26 while(b){ 27 if(b & 1){ 28 ans = mulmod(ans,a,p) % p; 29 b--; 30 } 31 b >>= 1; 32 a = mulmod(a,a,p) % p; 33 } 34 return ans; 35 } 36 37 38 void solve(){ 39 if(n == 1){ 40 printf("%I64d\n",n%p); 41 return; 42 } 43 printf("%I64d\n",(quick_mod(2,n,p)-2 + p)%p); 44 } 45 46 int main(){ 47 while(scanf("%I64d %I64d",&n,&p) != EOF){ 48 solve(); 49 } 50 return 0; 51 }
hdu 2191
多重背包
想起最开始学背包的时候,只学了完全背包,01背包
因为看不懂二进制那一块儿-------就一直没有去学-----
今天看了下,发现貌似略懂一点了
二进制的看的这个 http://blog.youkuaiyun.com/lyhvoyage/article/details/8545852
证明看得还有点不通
举个例子 17,从 1 到 17画了几下,发现是这样的
然后 代码看的这个 http://blog.youkuaiyun.com/acdreamers/article/details/8563283


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 1005; 9 int dp[maxn],n,m; 10 int c[maxn],w[maxn],num[maxn]; 11 12 void lingyi_pack(int cost,int weight,int m){ 13 for(int i = m;i >= cost;i--) { 14 dp[i] = max(dp[i],dp[i-cost]+weight); 15 } 16 } 17 18 void wanquan_pack(int cost,int weight,int m){ 19 for(int i = cost;i <= m;i++){ 20 dp[i] = max(dp[i],dp[i-cost]+weight); 21 } 22 } 23 24 void duochong_pack(int c[],int w[],int num[],int n,int m){ 25 memset(dp,0,sizeof(dp)); 26 27 for(int i = 1;i <= n;i++){ 28 if(num[i]*c[i] > m) wanquan_pack(c[i],w[i],m); 29 else{ 30 int k = 1; 31 while(k < num[i]){ 32 lingyi_pack(k*c[i],k*w[i],m); 33 num[i] -= k; 34 k <<= 1; 35 } 36 lingyi_pack(num[i]*c[i],num[i]*w[i],m); 37 } 38 } 39 40 // for(int i = 1;i <= m;i++) printf("dp[%d] = %d\n",i,dp[i]); 41 42 printf("%d\n",dp[m]); 43 } 44 45 int main(){ 46 int T; 47 scanf("%d",&T); 48 while(T--){ 49 memset(c,0,sizeof(c)); 50 memset(w,0,sizeof(w)); 51 memset(num,0,sizeof(num)); 52 scanf("%d %d",&m,&n); 53 for(int i = 1;i <= n;i++) scanf("%d %d %d",&c[i],&w[i],&num[i]); 54 55 duochong_pack(c,w,num,n,m); 56 } 57 return 0; 58 }
---------9.16
感觉这几天因为协会的事情,都静不下来
老是心里挂着有事情----
不应该这样的-------------------------------------------
没事,,加油加油
加油--
hdu 5439
想一早上终于想通了
其实比赛的时候,学弟想对了一点的 ans[i] = sigma i*a[i]
当时我们想的是,n太大了,数组根本开不下来
都有种弃疗的感觉,根本没再仔细往下想了
观察这列数
编号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
数 1 2 2 3 3 4 4 4 5 5 5 6 6 6 7 7 7 7 8 8 8 8
ans[ 1] = 1*1
ans[2] = 1*1 + 2*2
ans[3] = 1*1 + 2*2 + 3*2
ans[4] = 1*1 + 2*2 + 3*2 + 4*3
ans[5] = 1*1 + 2*2 + 3*2 + 4*3+5*3
ans[6] = 1*1 + 2*2 + 3*2 + 4*3 + 5*3 + 6*4
ans[7] = 1*1 + 2*2 + 3*2 + 4*3 + 5*3 + 6*4 + 7*4
ans[8] = 1*1 + 2*2 + 3*2 + 4*3 + 5*3 + 6*4 + 7*4 + 8*4
然后我就卡住了,还在往递推那边想--挫爆-----
然后其实可以合并一下
比如说
ans[6] = 1*1 + 2*(2+3) + 3*(4+5) + 4*(6)
ans[7] = 1*1 + 2*(2+3) + 3*(4+5) + 4*(6+7)
ans[8] = 1*1 + 2*(2+3) + 3*(4+5) + 4*(6+7+8)
观察到它们有公共的前缀,然后把这个公共的前缀处理出来,剩下的那一段算出来再加上去
然后前缀的计算办法
首先定义f[i] 为 i 出现的最后的位置,g[i] 表示i连续出现的次数
f[i] = f[i-1] + g[i]
然后就是求g[i]
g[i] = lower_bound(f+1,f+i,i) - f;
这个举两个例子就好想了
然后就是
ans里面括号里面的值的计算
首项 f[i-1] + 1,尾项 f[i],个数 g[i] = (f[i] - f[i-1])
根据等差数列的公式就可以算出来是 (f[i-1] + 1 + f[i]) *(f[i] - f[i-1])/2
看的是这篇题解
http://www.cnblogs.com/CSU3901130321/p/4805973.html


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 typedef long long LL; 9 const int maxn = 500000; 10 const int mod = 1e9+7; 11 LL f[maxn+5],g[maxn+5]; 12 LL ans[maxn+5]; 13 int n; 14 15 int main(){ 16 int T; 17 f[1] = 1;g[1] = 1; 18 f[2] = 3;g[2] = 2; 19 20 for(int i = 3;i <= maxn;i++){ 21 g[i] = lower_bound(f+1,f+i,i)-f; 22 f[i] = f[i-1] + g[i]; 23 } 24 ans[1] = 1; 25 26 for(int i = 2;i <= maxn;i++){ 27 ans[i] = ans[i-1] + 1LL*(f[i]+f[i-1]+1)*(f[i]-f[i-1])/2 %mod * 1LL *i %mod; 28 } 29 30 // for(int i = 1;i <= 10;i++) 31 // printf("f[%d] = %I64d g[%d] = %I64d ans[%d] = %I64d \n",i,f[i],i,g[i],i,ans[i]); 32 33 scanf("%d",&T); 34 while(T--){ 35 scanf("%d",&n); 36 int pos = lower_bound(f+1,f+maxn+1,n)-f; 37 // printf("pos = %d\n",pos); 38 LL res = ans[pos-1]; 39 40 for(int i = f[pos-1]+1;i <= n;i++){ 41 res = (res + 1LL*pos*i)%mod; 42 } 43 44 printf("%I64d\n",res); 45 } 46 return 0; 47 }
这场网络赛先补到这儿了吧先--
昨晚试图补那题多重背包,想好久一点思路没有
搜题解发现用到两次多重背包,然后通过空间联系起来---
实在不懂---再补吧-----
KMP +最小表示法没学过,,,或者用后缀数组(也没学过)做的那题也先不补吧-------
接着滚去 cf 上做题了---
加油↖(^ω^)------
cf 216 b
http://codeforces.com/contest/216/problem/B
给出n个人,m个仇恨关系,现在要把这n人平均分成两只队伍,且每只队伍里面不能有相互仇恨的人,问至少得删除多少个人
觉得自己想得情况有点多
先是偶链,偶环不用管
然后是奇点(1个点单独成联通快)的个数 c1
奇链的个数 c2
奇环的个数 c3
每个奇环肯定得删去一个点
然后如果是
偶数个奇点,偶数条奇链,不用管
偶数个奇点,奇数条奇链,删一个点
奇数个奇点,偶数条奇链,删一个点
奇数个奇点,奇数条奇链,不用管
发现做这样的题,得多画几个图,,先一点思路都没有,,还在往二分图那边想---


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 105; 9 vector<int> g[maxn]; 10 vector<int> c[maxn]; 11 int cnt; 12 int n,m; 13 int vis[maxn]; 14 int findd,ok,st; 15 16 void dfs(int u,int fa){ 17 vis[u] = 1; 18 c[cnt].push_back(u); 19 for(int i = 0;i < g[u].size();i++){ 20 int v = g[u][i]; 21 if(v == fa) continue; 22 if(!vis[v]) dfs(v,u); 23 else{ 24 findd = 1;st = v;return; 25 } 26 if(findd){ 27 if(ok) return; 28 if(st == u) ok = 1; 29 return; 30 } 31 } 32 } 33 34 void solve(){ 35 memset(vis,0,sizeof(vis)); 36 for(int i = 1;i <= n;i++) c[i].clear(); 37 38 cnt = 1; 39 int c1 = 0,c2 = 0,c3 = 0; 40 for(int i = 1;i <= n;i++){ 41 if(!vis[i]){ 42 findd = 0;ok = 0; 43 dfs(i,0); 44 if(findd && ok && c[cnt].size() %2 == 1) c3++; 45 if(c[cnt].size() == 1) c1++; 46 if(findd == 0 && ok == 0 && c[cnt].size()%2 == 1 && c[cnt].size() != 1) c2++; 47 cnt++; 48 } 49 } 50 51 int res = 0; 52 res += c3; 53 if(c1%2 == 1 && c2%2 == 0) res++; 54 if(c1%2 == 0 && c2%2 == 1) res++; 55 printf("%d\n",res); 56 } 57 58 int main(){ 59 while(scanf("%d %d",&n,&m) != EOF){ 60 for(int i = 1;i <= n;i++) g[i].clear(); 61 62 for(int i = 1;i <= m;i++){ 63 int u,v; 64 scanf("%d %d",&u,&v); 65 g[u].push_back(v);g[v].push_back(u); 66 } 67 solve(); 68 } 69 return 0; 70 }
cf 522 b
http://codeforces.com/problemset/problem/522/B
大意是这样的,给出n个矩形的宽 w,高 h
每次去掉当前这个矩形,求剩下的sigma w i * max(h[i])
因为是点的dp标签做的---
所以一直想怎么dp
后来--咦,用线段树查最大值呢---
于是,就每次这样蠢蠢的去查最大值
先将要去掉的那个点置为-1,再查询整个区间的最大值,再把这个值update回来---
可是不对--
每次执行的时候打印了一下线段树那个1---发现根本不是我预期的效果嘛---有些段的最大值还会是上一次的最大值--
后来就分两段查询,i的前面和后面
too young啊----
后来搜别人的题解---根本没有用线段树,维护一个最大值和次大值----55555555555555555


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 9 10 const int maxn = 200005; 11 int w[maxn],h[maxn],res[maxn]; 12 int n; 13 int nmax; 14 15 struct node{ 16 int l,r,maxx; 17 }t[4*maxn]; 18 19 void Push_up(int p){ 20 t[p].maxx = max(t[p<<1].maxx,t[p<<1|1].maxx); 21 } 22 23 void Build_tree(int p,int l,int r){ 24 t[p].l = l; 25 t[p].r = r; 26 if(l == r){ 27 t[p].maxx = h[l]; 28 return; 29 } 30 int mid = getmid(l,r); 31 Build_tree(p<<1,l,mid); 32 Build_tree(p<<1|1,mid+1,r); 33 Push_up(p); 34 } 35 36 void update(int idx,int p,int w){ 37 if(t[p].l == t[p].r){ 38 t[p].maxx = w; 39 return; 40 } 41 int mid = getmid(t[p].l,t[p].r); 42 if(idx <= mid) update(idx,p<<1,w); 43 else update(idx,p<<1|1,w); 44 Push_up(p); 45 } 46 47 void Query(int p,int l,int r){ 48 if(t[p].maxx <= nmax) return; 49 if(t[p].l == l && t[p].r == r){ 50 nmax = max(nmax,t[p].maxx); 51 return; 52 } 53 int mid = getmid(t[p].l,t[p].r); 54 if(r <= mid) Query(p<<1,l,r); 55 else if(l > mid) Query(p<<1|1,l,r); 56 else{ 57 Query(p<<1,l,mid); 58 Query(p<<1|1,mid+1,r); 59 } 60 } 61 62 int main(){ 63 while(scanf("%d",&n) != EOF){ 64 memset(w,0,sizeof(w)); 65 memset(h,0,sizeof(h)); 66 memset(res,0,sizeof(res)); 67 int sum = 0; 68 for(int i = 1;i <= n;i++) scanf("%d %d",&w[i],&h[i]),sum += w[i]; 69 Build_tree(1,1,n); 70 71 // for(int i = 1;i <= 2*n;i++) 72 // printf("t[%d].l = %d t[%d].r = %d t[%d].maxx = %d\n",i,t[i].l,i,t[i].r,i,t[i].maxx); 73 74 for(int i = 1;i <= n;i++){ 75 nmax = -1; 76 if(i-1 > 0) Query(1,1,i-1); 77 int a = nmax;//printf("i = %d a= %d\n",i,a); 78 if(i+1 <= n) Query(1,i+1,n); 79 int b = nmax;//printf("i = %d b = %d\n",i,b); 80 nmax = max(a,b); 81 // printf("i = %d nmaxx = %d\n",i,nmax); 82 res[i] = (sum-w[i])*nmax; 83 } 84 85 for(int i = 1;i <= n;i++) printf("%d ",res[i]); 86 printf("\n"); 87 } 88 return 0; 89 }
---------9.17
昨晚的cf
cf 575 c
http://codeforces.com/problemset/problem/579/C
C题被卡掉了
今早把输出改成 .9lf就过了-----哭开------
可是我记得以前做这样的题的时候,输出%lf都可以的啊-------
仔细仔细----加油


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 int a,b; 8 9 void solve(){ 10 if(a == b){ 11 printf("%lf\n",1.0*a); 12 return; 13 } 14 double x1 = 0,x2 = 0; 15 double c1 = (1<<30)-1,c2 =(1<<30)-1; 16 x1 = a-b; 17 x2 = a+b; 18 int y1 = 0,y2 = 0; 19 y1 = a/b-1; 20 if(y1 % 2 == 1) y1--; 21 y2 = a/b + 1; 22 if(y2%2 == 1) y2--; 23 24 //printf("y1 = %d y2 = %d\n",y1,y2); 25 26 if(y1 > 0) c1 = x1/y1; 27 if(y2 > 0) c2 = x2/y2; 28 29 double res = 0; 30 res = min(c1,c2); 31 if(res == ((1<<30)-1)) puts("-1"); 32 else printf("%.9lf\n",res); 33 } 34 35 int main(){ 36 while(scanf("%d %d",&a,&b) != EOF){ 37 solve(); 38 } 39 return 0; 40 }
cf 579 d
http://codeforces.com/problemset/problem/579/D
给出 n,k,d
再给出n个数,允许k次操作,每次操作可以将其中一个数乘以一个x
问这列数的异或的最大值
第一反应是dp---
在想怎么转移---不会啊--
后来又想,贪吧,能够让二进制的位数最长不就可以了么,于是把最大值扫出来,k次操作全部用在最大值上面---wawawa---
今天看题解--
枚举一下把这k次操作放在哪个数上,维护一个最大值就可以了
还有---我太挫了--不会算,每次枚举的时候,除开那个数另外的数的异或起来的值
还在想如果再去for算一遍,绝对T掉啊------
后来CF上翻了份代码-----处理下前缀的异或和后缀的异或就可以了
可是为什么要这样做呢------
搞懂了再来补上吧--


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 200005; 9 LL a[maxn]; 10 int n,k,x; 11 LL pre[maxn],suf[maxn]; 12 13 void solve(){ 14 memset(suf,0,sizeof(suf)); 15 memset(pre,0,sizeof(pre)); 16 17 for(int i = 1;i <= n;i++) pre[i] = pre[i-1]|a[i]; 18 for(int i = n;i >= 1;i--) suf[i] = suf[i+1]|a[i]; 19 20 // for(int i = 1;i <= n;i++){ 21 // printf("pre[%d] = %I64d suf[%d] = %II64d\n",i,pre[i],i,suf[i]); 22 // } 23 24 LL res = -1; 25 for(int i = 1;i <= n;i++){ 26 for(int j = 1;j <= k;j++) a[i] = a[i]*x; 27 LL tmp = pre[i-1]|suf[i+1]|a[i]; 28 res = max(res,tmp); 29 } 30 printf("%I64d\n",res); 31 } 32 33 int main(){ 34 while(scanf("%d %d %d",&n,&k,&x) != EOF){ 35 for(int i = 1;i <= n;i++) scanf("%I64d",&a[i]); 36 solve(); 37 } 38 return 0; 39 }
----9.18
出题解了,不知道是不是这样理解
假设把那k次分给不止一个数来乘
设这会儿得到的序列为b[]
那么在这乘了x的数中,肯定会有一个最大值,而且这还是在乘的次数不够k次的时候,它就最大了,要更大的话,就把所有的k次都乘给它
但是不知道都乘在哪个数上会最大,所以就去枚举一下
cf 577 E
http://codeforces.com/problemset/problem/577/E
给出 n个点的坐标,输出一种这n个点的排列方式,使得它们的曼哈顿距离之和小于等于25*10^8
尝试了各种排序之后无果--滚去看了题解--
有题解说是构造,有题解说是分块,意思都差不多的感觉
将x按照1000来分块
这样,在每一块里面,对y排序,
比如说第一块,从y由大到小
第二块,从y由小到大
这样顺次连接
可以估算出,每一块的y加起来是小于10^6,总共的x加起来小于 n*10^3(画了个图)
所以是满足的,,,
话说,做这题有个小插曲---
下午-
自动控制课---
拿着爪机坐在最后一排正瞅着这道题---
突然--
我们和蔼可亲的自动控制老师顿地一下---
“后面那个----------------------------”
我以为他要说,后面那个玩手机的同学,,,,,,,,
吓得飞起---
然后他说
“放大器应该这样来分析----------”


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int maxn = 1000005; 9 vector<pair<int,int> > res[maxn]; 10 11 int main(){ 12 int n; 13 while(scanf("%d",&n) != EOF){ 14 for(int i = 0;i < n;i++){ 15 int x,y; 16 scanf("%d %d",&x,&y); 17 res[x/1000].push_back(make_pair(y,i)); 18 } 19 for(int i = 0;i <= 1000;i++){ 20 if(res[i].size() == 0) continue; 21 sort(res[i].begin(),res[i].end()); 22 if(i%2 == 0) reverse(res[i].begin(),res[i].end()); 23 24 for(int j = 0;j < res[i].size();j++) printf("%d ",res[i][j].second+1); 25 } 26 } 27 return 0; 28 }
---------9.18
cf 150 b
http://codeforces.com/contest/150/problem/B
给出 n,m,k
要求意思是,长度为n的字符串,现在有m个不同的字母,要求长度为n的字符串的长度为k的子串全是回文串
问符合这样条件的字符串有多少个
想两天没有想出来,还是看题解了
首先考虑到回文串的特点,就把必须相同的位置合并在一起,
然后最后统计一下有多少个连通块c
连通块与连通块之间是可以任意填不同的字母的
所以答案是 m ^c


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 typedef long long LL; 9 const int maxn = 2005; 10 const int mod = 1e9+7; 11 int p[maxn]; 12 int n,m,k; 13 14 int find(int x){ return x == p[x] ? x : p[x] = find(p[x]);} 15 16 LL quick_mod(LL a, LL b,LL p){ 17 LL ans = 1; 18 a %= p; 19 while(b){ 20 if(b & 1){ 21 ans = ans * a % p; 22 b--; 23 } 24 b >>= 1; 25 a = a * a % p; 26 } 27 return ans; 28 } 29 30 void solve(){ 31 for(int i = 1;i <= n-k+1;i++){ 32 for(int j = i;j <= i+k-1;j++){ 33 int a = j; 34 int b = (i+i+k-1)-j; 35 int x = find(a); 36 int y = find(b); 37 if(x != y) p[x] = y; 38 } 39 } 40 int c = 0; 41 42 // for(int i = 1;i <= n;i++) printf("find(%d) = %d\n",i,find(i)); 43 44 for(int i = 1;i <= n;i++) if(find(i) == i) c++; 45 // printf("c = %d\n",c); 46 47 LL res = 0; 48 res = quick_mod(m,c,mod); 49 printf("%I64d\n",res); 50 } 51 52 int main(){ 53 while(scanf("%d %d %d",&n,&m,&k) != EOF){ 54 for(int i = 1;i <= n;i++) p[i] = i; 55 56 solve(); 57 } 58 return 0; 59 }
--------9.19
上午学了下单调栈
下午沈阳网络赛被打惨----
不知道碰到多少次LCA了,都没有去好好学一下--
不说了
--------9.20
学了一下在线的LCA
发现昨天的1003分明就是这一题,,,POJ 3417
http://www.cnblogs.com/scau20110726/archive/2013/05/31/3110666.html
还在想网络流---挫爆了---
hdu 5452


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 8 const int INF = (1<<30)-1; 9 const int maxn = 40005; 10 const int MAX_LOG = 16; 11 12 int n,m; 13 int first[maxn],ecnt,ecnt1,first1[maxn]; 14 int fa[MAX_LOG][maxn],dep[maxn]; 15 int dp[maxn],vis[maxn]; 16 17 struct Edge{ 18 int u,v,next,w; 19 }; 20 21 Edge e[10*maxn],ea[10*maxn]; 22 23 void init(){ 24 ecnt = 0; 25 memset(first,-1,sizeof(first)); 26 } 27 28 void Add_edge(int u,int v){ 29 e[ecnt].u = u; 30 e[ecnt].v = v; 31 e[ecnt].next = first[u]; 32 first[u] = ecnt++; 33 } 34 35 void Dfs(int p,int pre,int d){ 36 fa[0][p] = pre; 37 dep[p] = d; 38 for(int i = first[p];~i;i = e[i].next){ 39 int v = e[i].v; 40 if(v == pre) continue; 41 Dfs(v,p,d+1); 42 } 43 } 44 45 void Pre(){ 46 Dfs(1,-1,0); 47 for(int k = 0;k+1 < MAX_LOG;++k){ 48 for(int v = 1;v <= n;v++){ 49 if(fa[k][v] < 0) fa[k+1][v] = -1; 50 else fa[k+1][v] = fa[k][fa[k][v]]; 51 } 52 } 53 } 54 55 int Lca(int u,int v){ 56 if(dep[u] > dep[v]) swap(u,v); 57 for(int k = MAX_LOG-1;k >= 0;--k){ 58 if(dep[v]-dep[u] & (1<<k)) 59 v = fa[k][v]; 60 } 61 if(u == v) return u; 62 for(int k = MAX_LOG-1;k >= 0;--k){ 63 if(fa[k][u] != fa[k][v]){ 64 u = fa[k][u]; 65 v = fa[k][v]; 66 } 67 } 68 return fa[0][u]; 69 } 70 71 void dfs(int u){ 72 vis[u] = 1; 73 for(int i = first[u];~i;i = e[i].next){ 74 int v = e[i].v; 75 if(vis[v]) continue; 76 dfs(v); 77 dp[u] += dp[v]; 78 } 79 } 80 81 int main(){ 82 int T; 83 scanf("%d",&T); 84 int kase = 0; 85 while(T--){ 86 scanf("%d %d",&n,&m); 87 init(); 88 memset(dp,0,sizeof(dp)); 89 for(int i = 1;i <= n-1;i++){ 90 int u,v; 91 scanf("%d %d",&u,&v); 92 Add_edge(u,v); 93 Add_edge(v,u); 94 } 95 96 Pre(); 97 for(int i = 1;i <= m-n+1;i++){ 98 int u,v; 99 scanf("%d %d",&u,&v); 100 dp[u]++;dp[v]++; 101 int lca = Lca(u,v); 102 //printf("lca (%d,%d) = %d\n",u,v,lca); 103 dp[lca] -= 2; 104 } 105 106 // for(int i = 1;i <= n;i++) printf("dp[%d] = %d\n",i,dp[i]); 107 108 memset(vis,0,sizeof(vis)); 109 dfs(1); 110 /// for(int i = 1;i <= n;i++) printf("dp[%d] = %d\n",i,dp[i]); 111 112 int res = INF; 113 for(int i = 2;i <= n;i++) res = min(res,dp[i]); 114 printf("Case #%d: %d\n",++kase,res+1); 115 } 116 return 0; 117 }