hdu 4670 点分治 + 哈希
来源:互联网 发布:除尘风道计算软件 编辑:程序博客网 时间:2024/05/21 05:19
这场比赛是我和杰哥两个人搞的,搞了三个小时才做两个题,几何题感觉有点思路,但最近做的不多,就懒得搞,最后想了想,反正队友搞不出其他题,自己艹出一个做的比较少的题娱乐一下吧,瞄了瞄做的比较少的题,1005,求合法点对的数量,这种题一眼题啊,分治 + 统计,XWLJ了,稍微推了下calc的过程,中间统计的时候一开始想用map,然后杰哥说可能爆吧,然后由于是比赛的后半期,也就懒得想,开了个哈希表就开始写了,巴拉巴拉敲了40分钟,在比赛结束的时候交了一发,显然无果。
但随后。。。。
发现可以用一个long long保存一个节点的30个信息,这样就避免了哈希表每次的初始化(这里坨坨要超时啊),直接用map也会很快,如果比赛的时候敲得就是map,早就AC了、、、、、好水啊,题水,人更水。。。。
还是贴个代码吧,很多注释都没去,懒得去了,我还是去做做点分治+FFT吧。。sad。。。。
/* **********************************************Author : wuyiqiCreated Time: 2013-8-13 11:34:59File Name : Cube number on a tree.cpp*********************************************** */#include<cstdio> #include<cstring> #include<vector> #include<map>#include<algorithm> using namespace std; typedef __int64 lld;const int maxn = 50010; lld val[maxn];int in[maxn][33];int pri[33];int K;int n;int head[maxn];int nxt[maxn*2];int pnt[maxn*2];int E ;void add(int a,int b){ pnt[E] = b; nxt[E] = head[a]; head[a] = E++;}const int H = 100007;struct Hash_table{ int head[H]; int nxt[maxn*2]; int cnt[maxn*2]; int biao[maxn*2][33]; int E; void init() { E = 0; memset(head,-1,sizeof(head)); } int find(lld num,int x[],bool flag) { int h = num % H; for(int i = head[h]; i != -1; i = nxt[i]) { bool f = true; for(int j = 0; j < K; j++) { if(biao[i][j] != x[j]) { f = false; break; } } if(f){ int ans = cnt[i]; if(flag) cnt[i] ++; return ans; } } if(flag) { cnt[E] = 1; for(int i = 0; i < K; i++) biao[E][i] = x[i]; nxt[E] = head[h]; head[h] = E++; } return 0; }}ta;struct fenzhi { bool Del[maxn]; int size[maxn]; int opt[maxn]; int tnode[maxn] , tns; int all[maxn][33],as; int ID[maxn]; void Dfs(int u,int f) { tnode[tns++] = u; size[u] = 1; opt[u] = 0; for(int i = head[u]; i != -1; i = nxt[i]) { int v = pnt[i]; if(!Del[v] && v != f) { Dfs(v,u); size[u] += size[v]; opt[u] = max(opt[u],size[v]); } } } int Get_Root(int u){ tns = 0; Dfs(u,-1); int mi = maxn , ans = -1; for(int i = 0; i < tns; i++) { opt[tnode[i]] = max(opt[tnode[i]],size[u]-size[tnode[i]]); if(opt[tnode[i]] < mi) { mi = opt[tnode[i]]; ans = tnode[i]; } } return ans; } void Get_Dis(int u,int fa){ // printf("u=%d\n",u); int fid ; if(fa != -1) { fid = ID[fa]; for(int i = 0; i < K; i++) { all[as][i] = all[fid][i] + in[u][i];// all[as][i] %= 3; if(all[as][i] >= 3) all[as][i] -= 3; } } else { for(int i = 0; i < K; i++) { all[as][i] = in[u][i] ; } } ID[u] = as; as++; for(int i = head[u]; i != -1; i = nxt[i]) { int v = pnt[i]; if(!Del[v] && v != fa) { Get_Dis(v,u); } } } void Solve(int u) { //printf("u=%d\n",u); u = Get_Root(u); // printf("u=%d\n",u); Ans += Calc(u,u,false); // printf("Ans=%d\n",Ans); // puts("ddd"); Del[u] = true; for(int i = head[u]; i != -1; i = nxt[i]) { int v = pnt[i]; if(!Del[v]) { int tmp = Ans; // printf("v=%d\n",v); Ans -= Calc(v,u,true); // printf("tmp=%d Ans=%d\n",tmp,Ans); } } // printf("u=%d aaaa Ans=%d\n",u,Ans); for(int i = head[u]; i != -1; i = nxt[i]) { int v = pnt[i]; if(!Del[v]) { Solve(v); } } } lld Calc(int u,int root,bool yes){ as = 0; Get_Dis(u,-1); /* for(int i = 0; i < as;i++) { for(int j = 0; j < K; j++) { // printf("all[%d][%d]=%d\n",i,j,all[i][j]); } }*/ if(yes) { // printf("u=%d root=%d\n",u,root); for(int i = 0; i < as; i++) { for(int j = 0; j < K; j++) { all[i][j] += in[root][j]; if(all[i][j] >= 3) all[i][j] -= 3; } } /* for(int i = 0; i < as; i++) { for(int j = 0; j < K; j++) { printf("all[%d][%d]=%d\n",i,j,all[i][j]); } }*/ } // printf("as=%d\n",as); lld ans = 0; // ta.init(); map<lld,int> tt; int start = (u == root) ? 1 : 0; for(int i = start; i < as; i++) { int x[33]; lld sum = 0 , g = 0; bool f = true; for(int j = 0; j < K; j++) { if(all[i][j] == 0) x[j] = 0; if(all[i][j] == 1) x[j] = 2; if(all[i][j] == 2) x[j] = 1; g<<=2; g |= x[j]; int tmp = all[i][j] - in[root][j]; if(tmp < 0) tmp += 3 ; sum<<=2; sum |= tmp;// sum = sum * 10 + tmp; if(all[i][j] != 0) f = false; } // puts("x:::"); // for(int j = 0; j < K; j++) printf("%d ",x[j]);puts(""); // puts("y:::"); // for(int j = 0; j < K; j++) printf("%d ",y[j]);puts(""); if(f && !yes) { ans++; // puts("fffff"); // puts("ddd"); }//printf("g=%d sum=%d\n",g,sum); ans += tt[g]; // printf("ans=%d\n",ans); tt[sum]++; } return ans; } lld gao() { Ans = 0; fill(Del,Del+n+1,false); Solve(1); return Ans; } lld Ans;}nice;int extr ;void split(int node,lld num) { if(num == 0) return ; bool f = true; for(int i = 0; i < K; i++) { in[node][i] = 0; if(num % pri[i] == 0) { while(num % pri[i] ==0) { num /= pri[i]; in[node][i]++; } } in[node][i] %= 3; if(in[node][i] != 0) f =false; } if(f) extr ++; // for(int i = 0; i < K; i++) printf("in[%d][%d]=%d\n",node,i,in[node][i]);}int get_val(){ int ret(0); char c; while((c=getchar())==' '||c=='\n'||c=='\r'); ret=c-'0'; while((c=getchar())!=' '&&c!='\n'&&c!='\r') ret=ret*10+c-'0'; return ret;}int main() { while(scanf("%d",&n)!=EOF) { E = 0; extr = 0; fill(head,head+n+1,-1); scanf("%d",&K); for(int i = 0; i < K; i++) {// scanf("%d",&pri[i]); pri[i] = get_val(); } lld num; for(int i = 1; i <= n; i++) { scanf("%I64d",&num); split(i,num); } E = 0; for(int i = 1,a,b; i < n; i++){ a = get_val(); b = get_val(); // scanf("%d%d",&a,&b); add(a,b); add(b,a); } printf("%I64d\n",nice.gao()+extr); } return 0;}/*42 2 5100 10 100 101 22 33 471 2 2 2 2 2 2 2 21 21 32 42 53 63 753 2 3 52500 200 9 270000 274 23 52 54 147163 2 3 56 1 30 150 150 121 22 41 33 53 6 */
- hdu 4670 点分治 + 哈希
- hdu 4918 点分治
- 【hdu 4812】点分治
- hdu 4670 Cube number on a tree(点分治)
- hdu 4670 树的分治-求点对的个数
- 【HDU】4670 Cube number on a tree 点分治
- HDU 4812 D Tree (树分治之点分治)
- 分治 hdu 1007 最近点问题
- 【HDU】4812 D Tree 点分治
- 【HDU】5016 Mart Master II 点分治
- HDU 5314 Happy King 点分治
- HDU 5469 Antonidas【点分治+hash】
- hdu-4812(树分治 点权)
- HDU 4812 D Tree 点分治
- HDU-5721 Palace(最接近点问题 分治)
- hdu 1007 平面最近点对 分治
- 【HDU】5571 tree【动态点分治】
- hdu 1007 最近点对-分治法
- 为未来准备
- 迅雷C++试题及解答
- windows redis (php-redis插件,redis-admin管理工具)使用
- HDU1003
- 互斥的数
- hdu 4670 点分治 + 哈希
- Java之对象序列化与反序列化
- Oracle 表操作-组函数
- 程序员的七夕节故事 你懂得
- JSP使用文件上传插件uploadify
- 网络流 费用流 模板 ISAP+SPFA+ZKW
- git工作总结
- 从Ubuntu 12.04 的网络连接图标不见了说起
- “你不适合做程序员”