HDU 4358 Boring Counting ★★(2012 Multi-University Training Contest 6)
2012-11-15 13:47
423 查看
问题抽象:区间内恰好出现K次的数的个数。
------------------------------------------------------------------
UESTC出的题就是神啊T_T。。。一开始想了个函数式线段树方法后来发现错了=。=,然后也没什么思路,就是找着官方题解的方法做的。
思路:
题解说的用树状数组,这里当然也可以用线段树维护,和上面一样,线段树第j个数表示区间[j, i]内出现k次的数有多少个,然后像题解一样维护即可。(这种维护方法值得好好研究&&学习呀~)
代码中也有比较详细的注释:
------------------------------------------------------------------
UESTC出的题就是神啊T_T。。。一开始想了个函数式线段树方法后来发现错了=。=,然后也没什么思路,就是找着官方题解的方法做的。
思路:
题解说的用树状数组,这里当然也可以用线段树维护,和上面一样,线段树第j个数表示区间[j, i]内出现k次的数有多少个,然后像题解一样维护即可。(这种维护方法值得好好研究&&学习呀~)
代码中也有比较详细的注释:
#include #include #include #include #include #include #include #include #include #include #include #define MID(x,y) ((x+y)>>1) using namespace std; const int maxn = 100100; int id,n,K; int ans[maxn]; int w[maxn],wb[maxn]; int vis[maxn]; int a[maxn]; //线性权值 int l[maxn],r[maxn]; //线性区间 vector v[maxn]; //边表 vector pos[maxn]; //记录某数出现的位置 int num[maxn]; //记录某个数出现多少次了 map M; //离散化 int mtot; struct ANS { int l,r; int id; }Q[maxn]; bool cmp(ANS a1, ANS a2) { return a1.r ::iterator vp; if (v[x].size()) for (vp = v[x].begin(); vp != v[x].end(); vp ++) dfs(*vp); r[x] = id; } } int sum[maxn<<2],add[maxn<<2]; void build(int l,int r,int rt) { sum[rt] = 0; add[rt] = 0; if (l == r) return ; int mid = MID(l,r); build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); } void pushdown(int rt,int w) { if (add[rt]) { add[rt<<1] += add[rt]; add[rt<<1|1] += add[rt]; sum[rt<<1] += add[rt] * (w - (w >> 1)); sum[rt<<1|1] += add[rt] * (w >> 1); add[rt] = 0; } } void update(int s,int t,int v,int l,int r,int rt) { if (s <= l && r <= t) { sum[rt] += v * (r - l + 1); add[rt] += v; return ; } pushdown(rt, r-l+1); int mid = MID(l,r); if (s <= mid) update(s,t,v,l,mid,rt<<1); if (mid < t) update(s,t,v,mid+1,r,rt<<1|1); } int query(int p,int l,int r,int rt) { if (l == p && r == p) { return sum[rt]; } pushdown(rt,r-l+1); int mid = MID(l,r); if (p <= mid) return query(p,l,mid,rt<<1); else return query(p,mid+1,r,rt<<1|1); } int main() { //freopen("data.txt","r+",stdin); int tt,caseo = 1; scanf("%d",&tt); while(tt--) { //Initialize mtot = id = 0; memset(v,0,sizeof(v)); memset(vis,0,sizeof(vis)); memset(pos,0,sizeof(pos)); memset(num,0,sizeof(num)); //input printf("Case #%d:\n",caseo ++); scanf("%d%d",&n,&K); for (int i = 1; i <= n; i ++) scanf("%d",&w[i]); for (int i = 1; i < n; i ++) { int a,b; scanf("%d%d",&a,&b); v[a].push_back(b); //边表 } //树形结构转线性结构 dfs(1); M.clear(); //权值离散化 for (int i = 1; i <= n; i ++) if (!M[a[i]]) M[a[i]] = ++ mtot; int q; scanf("%d",&q); for (int i = 0; i < q; i ++) { int p; scanf("%d",&p); Q[i].l = l[p]; Q[i].r = r[p]; Q[i].id = i; } sort(Q,Q+q,cmp); int pt = 0; build(1,n,1); for (int i = 1; i <= n; i ++) { pos[M[a[i]]].push_back(i); num[M[a[i]]] ++; if (num[M[a[i]]] >= K) if (num[M[a[i]]] == K) update(1,pos[M[a[i]]][0],1,1,n,1); else { int ss = (num[M[a[i]]] - K <= 2)?1:(num[M[a[i]]] - K - 2); update(ss,pos[M[a[i]]][num[M[a[i]]]-K-1],-1,1,n,1); update(pos[M[a[i]]][num[M[a[i]]]-K-1]+1,pos[M[a[i]]][num[M[a[i]]]-K],1,1,n,1); } else; while(pt < q && Q[pt].r == i) { ans[Q[pt].id] = query(Q[pt].l,1,n,1); pt ++; } } for (int i = 0; i < q; i ++) printf("%d\n",ans[i]); if (tt) printf("\n"); } return 0; }
相关文章推荐
- HDU 4358 Boring Counting ★★(2012 Multi-University Training Contest 6)
- hdu 4365 Palindrome graph (规律题 + 快速幂取模 2012 Multi-University Training Contest 7 )
- hdu 4317 Unfair Nim(状态压缩DP)——2012 Multi-University Training Contest 2
- hdu 4348 To the moon(线段树成段更新) 2012 Multi-University Training Contest 5
- 2012 Multi-University Training Contest 9 1009解题报告 HDU 4388
- hdu 4336 Card Collector 2012 Multi-University Training Contest 4
- HDU 4322 最大费用最大流 2012 Multi-University Training Contest 3
- hdu 4331 Image Recognition(DP+线段树)2012 Multi-University Training Contest 4
- hdu 4328 Cut the cake(最大子矩阵)2012 Multi-University Training Contest 3
- hdu 4340 Capturing a country(树形DP) 2012 Multi-University Training Contest 5
- hdu 4317 Unfair Nim (状态压缩DP) 【2012 Multi-University Training Contest 2】
- hdu 4322 Candy(最大费用流)2012 Multi-University Training Contest 3
- HDU 4342 History repeat itself 2012 Multi-University Training Contest 5
- hdu 4370 0 or 1 (最短路 // 01 规划 2012 Multi-University Training Contest 8 )
- 2012 Multi-University Training Contest 6-1009 hdu4358 Boring counting
- hdu 4385 Moving Bricks (状态压缩dp 2012 Multi-University Training Contest 9 )
- hdu 4379 The More The Better ( 2012 Multi-University Training Contest 8)
- HDU 4340 Capturing a country 2012 Multi-University Training Contest 5
- HDU 4349 Xiao Ming's Hope 2012 Multi-University Training Contest 5
- hdu 4336 容斥原理 2012 Multi-University Training Contest 4