【HDOJ】4358 Boring counting
基本思路是将树形结构转线性结构,因为查询的是从任意结点到叶子结点的路径。
从而将每个查询转换成区间,表示从该结点到叶子结点的路径。
离线做,按照右边界升序排序。
利用树状数组区间修改。
树状数组表示有K个数据的数量,利用pos进行维护。
假设现有的sz >= K, 那么需要对区间进行修改。
- /* 4358 */
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <map>
- #include <queue>
- #include <set>
- #include <stack>
- #include <vector>
- #include <deque>
- #include <algorithm>
- #include <cstdio>
- #include <cmath>
- #include <ctime>
- #include <cstring>
- #include <climits>
- #include <cctype>
- #include <cassert>
- #include <functional>
- #include <iterator>
- #include <iomanip>
- using namespace std;
- //#pragma comment(linker,"/STACK:102400000,1024000")
- #define sti set<int>
- #define stpii set<pair<int, int> >
- #define mpii map<int,int>
- #define vi vector<int>
- #define pii pair<int,int>
- #define vpii vector<pair<int,int> >
- #define rep(i, a, n) for (int i=a;i<n;++i)
- #define per(i, a, n) for (int i=n-1;i>=a;--i)
- #define clr clear
- #define pb push_back
- #define mp make_pair
- #define fir first
- #define sec second
- #define all(x) (x).begin(),(x).end()
- #define SZ(x) ((int)(x).size())
- #define lson l, mid, rt<<1
- #define rson mid+1, r, rt<<1|1
- typedef struct {
- int v, nxt;
- } edge_t;
- typedef struct node_t {
- int w, id;
- friend bool operator< (const node_t& a, const node_t& b) {
- if (a.w == b.w)
- return a.id < b.id;
- return a.w < b.w;
- }
- } node_t;
- typedef struct ques_t {
- int l, r, id;
- } ques_t;
- const int maxn = 1e5+;
- const int maxv = maxn;
- const int maxe = maxv * ;
- int head[maxv], l;
- edge_t E[maxe];
- int Beg[maxn], End[maxn];
- int val[maxn], W[maxn];
- node_t nd[maxn];
- vi pvc[maxn];
- int dfs_clock;
- int n, K;
- int a[maxn];
- ques_t Q[maxn];
- int ans[maxn];
- bool compq (const ques_t& a, const ques_t& b) {
- if (a.r == b.r)
- return a.l < b.l;
- return a.r < b.r;
- }
- void init() {
- memset(head, -, sizeof(head));
- memset(a, , sizeof(a));
- dfs_clock = l = ;
- }
- void addEdge(int u, int v) {
- E[l].v = v;
- E[l].nxt = head[u];
- head[u] = l++;
- E[l].v = u;
- E[l].nxt = head[v];
- head[v] = l++;
- }
- void dfs(int u, int fa) {
- int v, k;
- Beg[u] = ++dfs_clock;
- val[dfs_clock] = W[u];
- for (k=head[u]; k!=-; k=E[k].nxt) {
- v = E[k].v;
- if (v == fa)
- continue;
- dfs(v, u);
- }
- End[u] = dfs_clock;
- }
- int lowest(int x) {
- return x & -x;
- }
- int sum(int x) {
- int ret = ;
- while (x) {
- ret += a[x];
- x -= lowest(x);
- }
- return ret;
- }
- void update(int x, int delta) {
- while (x <= n) {
- a[x] += delta;
- x += lowest(x);
- }
- }
- void solve() {
- int q;
- int u, v;
- sort(nd+, nd++n);
- int cnt = ;
- W[nd[].id] = cnt;
- rep(i, , n+) {
- if (nd[i].w==nd[i-].w) {
- W[nd[i].id] = cnt;
- } else {
- W[nd[i].id] = ++cnt;
- }
- }
- dfs(, );
- rep(i, , cnt+) {
- pvc[i].clr();
- pvc[i].pb();
- }
- scanf("%d", &q);
- rep(i, , q) {
- scanf("%d", &u);
- Q[i].l = Beg[u];
- Q[i].r = End[u];
- Q[i].id = i;
- }
- sort(Q, Q+q, compq);
- int sz;
- int j = ;
- rep(i, , n+) {
- pvc[val[i]].pb(i);
- sz = SZ(pvc[val[i]]) - ;
- if (sz >= K) {
- if (sz > K) {
- update(pvc[val[i]][sz-K-]+, -);
- update(pvc[val[i]][sz-K]+, );
- }
- update(pvc[val[i]][sz-K]+, );
- update(pvc[val[i]][sz-K+]+, -);
- }
- while (j<q && Q[j].r==i) {
- ans[Q[j].id] = sum(Q[j].l);
- ++j;
- }
- }
- rep(i, , q)
- printf("%d\n", ans[i]);
- }
- int main() {
- ios::sync_with_stdio(false);
- #ifndef ONLINE_JUDGE
- freopen("data.in", "r", stdin);
- freopen("data.out", "w", stdout);
- #endif
- int t;
- int u, v;
- scanf("%d", &t);
- rep(tt, , t+) {
- init();
- scanf("%d %d", &n, &K);
- rep(i, , n+) {
- scanf("%d", &W[i]);
- nd[i].id = i;
- nd[i].w = W[i];
- }
- rep(i, , n) {
- scanf("%d %d", &u, &v);
- addEdge(u, v);
- }
- printf("Case #%d:\n", tt);
- solve();
- if (tt != t)
- putchar('\n');
- }
- #ifndef ONLINE_JUDGE
- printf("time = %d.\n", (int)clock());
- #endif
- return ;
- }
数据发生器。
- from copy import deepcopy
- from random import randint, shuffle
- import shutil
- import string
- def GenDataIn():
- with open("data.in", "w") as fout:
- t = 10
- bound = 10**9
- fout.write("%d\n" % (t))
- for tt in xrange(t):
- n = randint(100, 200)
- K = randint(1, 5)
- fout.write("%d %d\n" % (n, K))
- ust = [1]
- vst = range(2, n+1)
- L = []
- for i in xrange(n):
- x = randint(1, 100)
- L.append(x)
- fout.write(" ".join(map(str, L)) + "\n")
- for i in xrange(1, n):
- idx = randint(0, len(ust)-1)
- u = ust[idx]
- idx = randint(0, len(vst)-1)
- v = vst[idx]
- ust.append(v)
- vst.remove(v)
- fout.write("%d %d\n" % (u, v))
- q = n
- fout.write("%d\n" % (q))
- L = range(1, n+1)
- shuffle(L)
- fout.write("\n".join(map(str, L)) + "\n")
- def MovDataIn():
- desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
- shutil.copyfile("data.in", desFileName)
- if __name__ == "__main__":
- GenDataIn()
- MovDataIn()
【HDOJ】4358 Boring counting的更多相关文章
- 【HDOJ】3518 Boring Counting
后缀数组2倍增可解. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 10 ...
- 【HDOJ】P5056 Boring count
题目意思是给你一个字符串和K,让你求其中有多少个字串中每个字母的出现次数不超过K次,可以等于 题目意思是很简单的,写起来也很简单,不过就是注意最后要是long long要不WA了,555~ #incl ...
- HDU 4358 Boring counting(莫队+DFS序+离散化)
Boring counting Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 98304/98304 K (Java/Others) ...
- HDOJ 题目3518 Boring counting(后缀数组,求不重叠反复次数最少为2的子串种类数)
Boring counting Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU - 4358 Boring counting (dsu on tree)
Boring counting: http://acm.hdu.edu.cn/showproblem.php?pid=4358 题意: 求一棵树上,每个节点的子节点中,同一颜色出现k次 的 个数. 思 ...
- hdu 4358 Boring counting dfs序+莫队+离散化
Boring counting Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 98304/98304 K (Java/Others) ...
- 【BZOJ】4358: permu 莫队算法
[题意]给定长度为n的排列,m次询问区间[L,R]的最长连续值域.n<=50000. [算法]莫队算法 [题解]考虑莫队维护增加一个数的信息:设up[x]表示数值x往上延伸的最大长度,down[ ...
- (好题)树状数组+离散化+DFS序+离线/莫队 HDOJ 4358 Boring counting
题目传送门 题意:给你一棵树,树上的每个节点都有树值,给m个查询,问以每个点u为根的子树下有多少种权值恰好出现k次. 分析:首先要对权值离散化,然后要将树形转换为线形,配上图:.然后按照右端点从小到大 ...
- 【HDOJ】4729 An Easy Problem for Elfness
其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...
随机推荐
- NHibernate各种查询
NHibernate各种查询 NHibernate's methods of querying are powerful, but there's a learning curve. Longer t ...
- Java调用CMD命令
java的Runtime.getRuntime().exec(commandStr)可以调用执行cmd指令. cmd /c dir 是执行完dir命令后关闭命令窗口. cmd /k dir 是执行完d ...
- DTCMS自定义标签:获取所有栏目以及不显示指定栏目
DTcms.Web.UI\Label\category.cs中 添加下面代码 /// <summary> /// 返回所有类别 /// </summary> /// <r ...
- 【转】Qt使用自带的windeployqt 生成exe来发布软件
集成开发环境 QtCreator 目前生成图形界面程序 exe 大致可以分为两类:Qt Widgets Application 和 Qt Quick Application.下面分别介绍这两类exe ...
- Spark Streaming揭秘 Day12 数据安全容错(Executor篇)
Spark Streaming揭秘 Day12 数据安全容错(Executor篇) 今天,让我们研究下SparkStreaming在Executor端的数据安全及容错机制. 在SparkStreami ...
- 《C和指针》 读书笔记 -- 第8章 数组
1.在C中,数组名的值是一个指针常量而不是指针变量,也就是数组第一个元素的地址. 2.数组和指针的区别: 声明一个数组时,编译器将根据声明所指定的元素数量为数组保留内存空间,然后再创建数组名,它的值是 ...
- xaml中绑定单例属性
在项目中经常会遇到,同一个字典表绑定到多个ItemsControl上的情况,可以在单例中创建一个List,xaml上绑定即可.看代码: 1,XAML <Grid> <StackPan ...
- size()函数的使用
matlab中对于矩阵的计算是十分方便的,其中关于矩阵的函数有很多 size() 在c/c++中sizeof用来求某变量所占用的字节数,在matlab中size()则可以用来求矩阵的“长度”,矩阵的长 ...
- Oracle监听器—动态注册
注册就是将数据库作为一个服务注册到监听程序.客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库.这个服务名可能与实例名一样,也有可能不一样. 注册分: 1. 静 ...
- Kinetic使用注意点--lable
new Lable(config) 参数: config:包含所有配置项的对象. { x: "横坐标", y: "纵坐标", width: "宽度&q ...