BZOJ 2017省队十连测推广赛1
来源:互联网 发布:数据分析论坛推荐 编辑:程序博客网 时间:2024/05/29 07:09
A 4765 : 分块
B 4766 : 矩阵树定理或找规律
C 4767 : 容斥+DP
感觉难度应该是A>B>C?
可惜周二晚上在训练,不然也许就能全A了……
A 4765 普通计算姬
分块分块再分块……
想了一想感觉没什么树上的算法能用,考虑分块乱搞。把操作分根号块,每次进入新块时重建一整棵树。那么一次询问至多只会对应根号个修改。对于每一个点x,记录从x到根的路径上经过了1~n的哪些点,这同样也可以分块,对于根号个修改点直接查贡献即可。因为分块了,查完之后还会有一些块外小点没统计到。因小点不超过根号个,对于这些小点就暴力查子树和,这需要一种修改
#include<cstdio>#include<cstring>#define S 900#define N 200005#define ll unsigned long long#define R registerusing namespace std;namespace runzhe2000{ inline int read() { R int r = 0; R char c = getchar(); for(; c < '0' || c > '9'; c = getchar()); for(; c >='0' && c <='9'; r = r*10+c-'0', c = getchar()); return r; } ll sum[N], big[N], small[N]; int n, m, ecnt, d[N], last[N], root, beg[N], end[N], timer, fa[N], cnt[N][N/S+10], q[N], qv[S+10], qtop, bel[N], rebeg[N]; struct edge{int next, to;}e[N<<1]; void addedge(int a, int b) { e[++ecnt] = (edge){last[a], b}; last[a] = ecnt; } struct block { ll big[N/S+10],small[N]; block(){memset(big,0,sizeof big); memset(small,0,sizeof small);} void init() { memset(big,0,N<<3); memset(small,0,N<<3); } void add(int x, int v) { for(int i = bel[x], ii = N/S+10; i < ii; i++) big[i] += v; for(int i = x, ii = S*bel[x]; i <= ii; i++) small[i] += v; } ll query(int x) { if(!x) return 0; return big[bel[x]-1] + small[x]; } }blo; void init_sum(int x) { sum[x] = d[x]; for(int i = last[x]; i; i = e[i].next) { int y = e[i].to; if(y == fa[x]) continue; init_sum(y); sum[x] += sum[y]; } } void dfs(int x) { rebeg[beg[x] = ++timer] = x; memcpy(cnt[x], cnt[fa[x]], (N/S+10)<<2); for(int i = bel[x], ii = N/S+10; i < ii; i++) cnt[x][i]++; for(int i = last[x]; i; i = e[i].next) { int y = e[i].to; if(y == fa[x]) continue; fa[y] = x; dfs(y); } end[x] = timer; } ll calc(int lim) { if(!lim) return 0; R ll ret = sum[lim]; for(R int i = 1; i <= qtop; i++) ret += (ll)cnt[q[i]][bel[lim]-1] * qv[i]; for(int i = S*(bel[lim]-1)+1; i <= lim; i++) ret += blo.query(end[i]) - blo.query(beg[i]-1); return ret; } void main() { n = read(); m = read(); for(int i = 1; i <= n; i++) { d[i] = read(); bel[i] = bel[i-1] + (i%S==1?1:0); } for(int i = 1, a, b; i <= n; i++) { a = read(); b = read(); if(!a) {root = b; continue;} if(!b) {root = a; continue;} addedge(a, b); addedge(b, a); } dfs(root); blo.init(); for(R int i = 1, op, u, v; i <= m; i++) { op = read(), u = read(), v = read(); if(i % S == 1) { blo.init(); memset(sum,0,N<<3); init_sum(root); for(R int i = 1; i <= n; i++) sum[i] += sum[i-1]; qtop = 0; } if(op == 1) { q[++qtop] = u; qv[qtop] = v - d[u]; blo.add(beg[u], v - d[u]); d[u] = v; } else printf("%llu\n",calc(v) - calc(u-1)); } }}int main(){ runzhe2000::main();}
B 4766 文艺计算姬
考场上打表找出规律,答案为
#include<cstdio>#include<cstring>#define ll long longusing namespace std;namespace runzhe2000{ ll n, m, p; ll mul(ll a, ll b) { ll r = 0; for(; a; a >>= 1) { if(a & 1) r = (r + b) % p; b = (b + b) % p; } return r; } ll fpow(ll a, ll b) { ll r = 1; for(; b; b >>= 1) { if(b&1) r = mul(r, a); a = mul(a, a); } return r; } void main() { scanf("%lld%lld%lld",&n,&m,&p); printf("%lld\n",mul(fpow(n,m-1),fpow(m,n-1))); }}int main(){ runzhe2000::main();}
C 4767 两双手
把基底变成(0,1)(1,0),点坐标就好多了。显然容斥,记f[i][0/1]表示此时在i,已经至少经过的点数为偶数/奇数个时的方案数。由于图是拓扑图,可以直接DP出来。
#include<map>#include<cstdio>#include<algorithm>#define mkp(u,v) make_pair(u,v) #define N 505#define M 666666#define MOD 1000000007using namespace std;namespace runzhe2000{ typedef long long ll; const double eps = 1e-3; struct point{int x, y;}p[N]; int Ex, Ey, Ax, Ay, Bx, By, n, ecnt, pcnt, f[N][2], fac[M], inv[M], inc[M], deg[N], q[N], last[N]; struct edge{int next, to;}e[N*N]; map<pair<int,int>,bool> vis; void addedge(int a, int b) { e[++ecnt] = (edge){last[a], b}; last[a] = ecnt; } bool addpoint(int x, int y) { int nx = By ? ((double)y * Bx / By - x) / ((double)Ay * Bx / By - Ax) + eps: ((double)x * By / Bx - y) / ((double)Ax * By / Bx - Ay) + eps; int ny = Ax ? ((double)x * Ay / Ax - y) / ((double)Bx * Ay / Ax - By) + eps: ((double)y * Ax / Ay - x) / ((double)By * Ax / Ay - Bx) + eps; if(x != nx * Ax + ny * Bx || y != nx * Ay + ny * By || nx < 0 || ny < 0 || vis[mkp(nx,ny)]) return false; vis[mkp(nx,ny)] = 1; p[++pcnt] = (point){nx, ny}; return true; } int C(int a, int b){return (ll)fac[a] * inc[b] % MOD * inc[a-b] % MOD;} void main() { fac[0] = fac[1] = inv[1] = inc[1] = inc[0] = 1; for(int i = 2; i < 666666; i++) { fac[i] = (ll)fac[i-1] * i % MOD; inv[i] = (ll)(MOD - MOD/i) * inv[MOD % i] % MOD; inc[i] = (ll)inc[i-1] * inv[i] % MOD; } scanf("%d%d%d%d%d%d%d",&Ex,&Ey,&n,&Ax,&Ay,&Bx,&By); addpoint(0,0); for(int i = 1, x, y; i <= n; i++) { scanf("%d%d",&x,&y); if(x == 0 && y == 0){puts("0"); return;} if(x == Ex && y == Ey){puts("0"); return;} addpoint(x,y); } if(Ex == 0 && Ey == 0) {puts("1"); return;} if(!addpoint(Ex,Ey)) {puts("0"); return;} for(int i = 1; i <= pcnt; i++) for(int j = 1; j <= pcnt; j++) if(i != j && p[i].x <= p[j].x && p[i].y <= p[j].y) addedge(i, j), deg[j]++; q[0] = 1; f[1][1] = 1; for(int head=0, tail=1; head<tail; head++) { int x = q[head]; for(int i = last[x]; i; i = e[i].next) { int y = e[i].to, P = C(p[y].y - p[x].y + p[y].x - p[x].x, p[y].x - p[x].x); (f[y][0] += (ll)f[x][1] * P % MOD) %= MOD; (f[y][1] += (ll)f[x][0] * P % MOD) %= MOD; if(!(--deg[y])) q[tail++] = y; } } printf("%d\n",((f[pcnt][0] - f[pcnt][1]) % MOD + MOD) % MOD); }}int main(){ runzhe2000::main();}
0 0
- BZOJ 2017省队十连测推广赛1
- bzoj [ 2017省队十连测推广赛1 ] ( 4765 && 4766 && 4767 )题解
- [BZOJ Contest-2017省队十连测推广赛1·T1][BZOJ4765][分块][dfs序]普通计算姬
- [BZOJ Contest-2017省队十连测推广赛1·T3][BZOJ4767][DP][容斥原理]两双手
- [BZOJ Contest-2017省队十连测推广赛1·T2][BZOJ4766][完全二分图的生成树个数]文艺计算姬
- [BZOJ Contest-2017省队十连测推广赛2·T2][BZOJ4771][主席树][dfs序]七彩树
- [BZOJ Contest-2017省队十连测推广赛2·T3][BZOJ4256][DP][Tarjan]推箱子
- [比赛][2017省队十连测推广赛1]
- 推广
- bzoj4766 文艺计算姬(2017省选推广赛B)(含证明?)
- 2017年SEO推广优化怎么做
- 微软与网易联手推广Silverlight1.1
- 微信互联网推广经验7+1
- 收费软件推广模式探索1
- BZOJ-2017十一月份月赛总结
- 百度推广&&360推广
- BZOJ九月月赛
- bzoj快乐刷水篇(1)
- 有关存储区的区域分配问题
- mac双开eclipse
- centos 安装 MySQLdb 和 psycopg2
- js日期格式化: javascript Date format()
- editplus快捷键汇总
- BZOJ 2017省队十连测推广赛1
- pci_bus_type/amba_bustype/platform_bus_type 下的driver使用smmu
- HashMap 内部原理
- Class bytes found but defineClass()failed for: 错误解决
- 04-线程设计
- 欢迎使用CSDN-markdown编辑器
- app 优化-提高ios app性能的建议和技巧
- android跨进程通信(一)
- Python编码规范:IF中的多行条件