问题抽象:区间内恰好出现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--){//Initializemtot = id = 0;memset(v,0,sizeof(v));memset(vis,0,sizeof(vis));memset(pos,0,sizeof(pos));memset(num,0,sizeof(num));//inputprintf("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;
}

转载于:https://www.cnblogs.com/AbandonZHANG/archive/2012/11/15/4114165.html

HDU 4358 Boring Counting ★★(2012 Multi-University Training Contest 6)相关推荐

  1. 后缀数组 --- HDU 3518 Boring counting

    Boring counting Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,求:至少出 ...

  2. HDU 6091 - Rikka with Match | 2017 Multi-University Training Contest 5

    思路来自 某FXXL 不过复杂度咋算的.. /* HDU 6091 - Rikka with Match [ 树形DP ] | 2017 Multi-University Training Conte ...

  3. HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3

    /* HDU 6058 - Kanade's sum [ 思维,链表 ] | 2017 Multi-University Training Contest 3 题意:给出排列 a[N],求所有区间的第 ...

  4. 【HDOJ】4358 Boring counting

    基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径. 从而将每个查询转换成区间,表示从该结点到叶子结点的路径. 离线做,按照右边界升序排序. 利用树状数组区间修改. 树状数组表示有 ...

  5. HDU - 3518 Boring counting(后缀数组)

    题目链接:点击查看 题目大意:给出一个字符串,问有多少个子串出现了两次以上,计算时彼此不能覆盖 题目分析:因为数据范围比较小,我们可以直接暴力,枚举子串的长度,利用height数组的性质将后缀分为不同 ...

  6. 9行代码AC——HDU 6857 -Clockwise or Counterclockwise(2020 Multi-University Training Contest 8)(判断三点顺序)

    励志用尽量少的代码做高效表达 Problem Description It is preferrable to read the pdf statment. After some basic geom ...

  7. HDU 6386 Age of Moyu 2018 Multi-University Training Contest 7(最短路径dijkstra)

    Age of Moyu 题意:第一行给出n,m,接下来有m条路,每一行给出 a b c ,从a到b 是c掌控. 若下一条路与上一条路不属于一个c,需要缴费1. 输出从1到N的最小花费,不通则输出-1 ...

  8. Boring counting HDU - 3518 (后缀数组)

    Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...

  9. HDU 6051 - If the starlight never fade | 2017 Multi-University Training Contest 2

    /* HDU 6051 - If the starlight never fade [ 原根,欧拉函数 ] | 2017 Multi-University Training Contest 2 题意: ...

最新文章

  1. C++ [](){} 匿名函数 lambda表达式
  2. 功能分支重新设置后,Git推送被拒绝
  3. Hibernate持久化对象三种状态
  4. phpcms v9 配置sphinx全文索引教程
  5. 数据库简单的实际运用 ①
  6. Codeforces 173E Camping Groups 线段树
  7. 2010年3月再谈前端工程师的笔试题
  8. 是做生意还是做事业,这是一个问题。
  9. 深入解构magnitude_spectrum()
  10. Cglib 代码生成库使用快速入门
  11. 验证空间变形:电子在测地线的圆形轨道上辐射行为
  12. Error: ADB exited with exit code 1 Performing Streamed Install adb: failed to install D:\svn\app\sm
  13. Egencia smartmix航班排名模型背后的运营研究
  14. win10 c++调用pytorch模型
  15. 思杰desktop7.6申请90天试用的License
  16. 跳转到App Store 指定的app
  17. linux服务器基于poco,基于C++ Poco框架的HTTP动态服务器
  18. ESP32学习笔记(49)——RFID RC522使用
  19. twitter系统架构
  20. Nginx学习笔记(二):反向代理

热门文章

  1. Flink的Group by window图示(转载)
  2. Kafka->Flink->Hbase(纯DDL/DML形式)
  3. spark-submit提交参数说明以及与yarn-site.xml中参数的相互约束关系+spark运行架构图解(持续更新中)
  4. django-oscar-paypal出现UnicodeEncodeError: 'latin-1' codec can't encode characters in position XXXX
  5. intellij中出現org.apache.hadoop.fs.FSDataInputStream解決方案
  6. 列举mysql的所有触发器以及删除触发器
  7. 数据结构:二分查找python实现
  8. 机器学习(六)——SVM(4)、学习理论
  9. OpenGL研究, GUI框架分析, 虚拟机比较, Win10历险记, WxWidget, uboot, WireShark
  10. Windows 10 中 VMware 要求禁用 Device Guard 问题