hdu 4358 欧拉树形变线性+树状数组+离散化+离线+区间内出现k次的不同的数有几个+手动扩展栈

本文主要是介绍hdu 4358 欧拉树形变线性+树状数组+离散化+离线+区间内出现k次的不同的数有几个+手动扩展栈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://acm.hdu.edu.cn/showproblem.php?pid=4358

性价比很高的一道题,一题练很多东西,逐一道来:
1、离散化的一种方法:

我在http://blog.csdn.net/u011026968/article/details/38542827里面写了一种离散化的方法,但是当时认为这种方法没法处理有重复元素的,这篇博客里的离散化的方法完善了我之前写的,可以保证相同元素离散化之后仍然相同,不同元素离散化之后仍然不同

其中a[]存的是待离散化的数

bool cmp(const int x,const int b)
{
return a[x]<a[b];
}
void dis()//离散化的方法---保证原来相等的还想等,不等的还不等,O(nlogn)
{
int tmpdis[MAXN];
for(int i=0;i<=N;i++)
tmpdis[i]=i;
sort(tmpdis+1,tmpdis+1+N,cmp);
int tmp=0,prev=a[tmpdis[1]]-1;//pre初始化的时候保证和第一个数不一样,因为已经排过序,所以最小的数-1满足需求
for(int i=1;i<=N;i++)
{
if(prev!=a[tmpdis[i]])
{
prev=a[tmpdis[i]];
a[tmpdis[i]]=++tmp;//两句不可以互换
}
else
{
a[tmpdis[i]]=tmp;
}
}
}
2、欧拉树形变线性

之前做过一道LCA的题---其实到现在还没有AC,,,学到的树形变线性,其实就是记录先序遍历的结果

调用直接dfs(root),root为树根,最终在li[]里面存储了结果,以u为根的子树的区间是le[u],rig[u],

void dfs(int u)
{vis[u]=1;le[u]=++treecnt;li[treecnt]=a[u];//已经离散化过的a[]for(int j=0;j<g[u].size();j++){int v=g[u][j];if(!vis[v])dfs(v);}rig[u]=treecnt;
}

3、树状数组+离线+区间内出现k次的不同的数有几个

我的方法参照之前一道CF的题:http://blog.csdn.net/u011026968/article/details/38589907

还看到一种方法:http://blog.csdn.net/julyana_lin/article/details/7872393

我看的不是很明白......不过跟我的另一篇博客应该是同样的方法:http://blog.csdn.net/u011026968/article/details/38583153

4、手动扩展栈

我RE了一下午,以为是自己的做法没想好导致错误-----然后手动模拟却觉得对,后来扩展栈,AC %>_<%

#pragma comment(linker, "/STACK:102400000,102400000")

其实G++交的话,不支持这句代码但是可以AC,不需要扩展栈

C++代码如下:

#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)const int MAXN = 100000+100;
int N,K;
int a[MAXN],vis[MAXN],tree[MAXN],treecnt;
int le[MAXN],rig[MAXN],c[MAXN*4],ans[MAXN];
int li[MAXN];vector<int>g[MAXN*2];struct Query
{int l,r,id;bool operator < (const Query &t)const{return r<t.r;}
}q[MAXN*4];inline int lowbit(int x){return x&(-x);}void add(int x, int v)
{while(x<=treecnt){c[x]+=v;x+=lowbit(x);}
}int sum(int x)
{int ret=0;while(x>0){ret+=c[x];x-=lowbit(x);}return ret;
}void dfs(int u)
{vis[u]=1;le[u]=++treecnt;li[treecnt]=a[u];//已经离散化过的a[]for(int j=0;j<g[u].size();j++){int v=g[u][j];if(!vis[v])dfs(v);}rig[u]=treecnt;
}void inittree()
{CL(tree,0);CL(vis,0);CL(le,0);CL(rig,0);treecnt=0;dfs(1);
}bool cmp(const int x,const int b)
{return a[x]<a[b];
}void dis()//离散化的方法---保证原来相等的还想等,不等的还不等,O(nlogn)
{int tmpdis[MAXN];for(int i=0;i<=N;i++)tmpdis[i]=i;sort(tmpdis+1,tmpdis+1+N,cmp);int tmp=0,prev=a[tmpdis[1]]-1;//pre初始化的时候保证和第一个数不一样,因为已经排过序,所以最小的数-1满足需求for(int i=1;i<=N;i++){if(prev!=a[tmpdis[i]]){prev=a[tmpdis[i]];a[tmpdis[i]]=++tmp;//两句不可以互换}else{a[tmpdis[i]]=tmp;}}
}
vector<int>data[MAXN];
int main()
{//IN("hdu4358.txt");int ncase,Q;int u,v,ic=0;scanf("%d",&ncase);while(ncase--){for(int i=0;i<MAXN;i++)data[i].clear();scanf("%d%d",&N,&K);for(int i=0;i<MAXN;i++)g[i].clear();///for(int i=1;i<=N;i++)scanf("%d",&a[i]);dis();//离散化for(int i=1;i<N;i++){scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);}inittree();//剩下的就是查找从scanf("%d",&Q);for(int i=1;i<=Q;i++){scanf("%d",&u);q[i].l=le[u];q[i].r=rig[u];q[i].id=i;//printf("u=%d l=%d r=%d\n",u,le[u],rig[u]);}sort(q+1,q+1+Q);/////for(int i=1;i<=treecnt;i++)// printf("a[%d]=%d li=%d\n",i,a[i],li[i]);///CL(c,0);for(int i=1,qu=1;i<=treecnt;i++)//{int vv=li[i];data[vv].push_back(i);int sz=data[vv].size();//K=li[i];if(sz>=K){add(data[vv][sz-K],1);if(sz>K)add(data[vv][sz-K-1],-2);if(sz>K+1)add(data[vv][sz-K-2],1);}while(q[qu].r==i && qu<=Q){ans[q[qu].id]=sum(i)-sum(q[qu].l-1);/////for(int i=1;i<=treecnt;i++)//   printf("##i=%d %d\n",i,c[i]);// printf("ans=%d id=%d l=%d r=%d\n",ans[q[qu].id],q[qu].id,q[qu].l,i);//qu++;}}printf("Case #%d:\n",++ic);for(int i=1;i<=Q;i++)printf("%d\n",ans[i]);if(ncase)putchar('\n');}return 0;
}

另外格式上---如果是case之间隔一个空行,最后一个case是不需要输出\n的,因为这个PE了





这篇关于hdu 4358 欧拉树形变线性+树状数组+离散化+离线+区间内出现k次的不同的数有几个+手动扩展栈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1009581

相关文章

每天认识几个maven依赖(ActiveMQ+activemq-jaxb+activesoap+activespace+adarwin)

八、ActiveMQ 1、是什么? ActiveMQ 是一个开源的消息中间件(Message Broker),由 Apache 软件基金会开发和维护。它实现了 Java 消息服务(Java Message Service, JMS)规范,并支持多种消息传递协议,包括 AMQP、MQTT 和 OpenWire 等。 2、有什么用? 可靠性:ActiveMQ 提供了消息持久性和事务支持,确保消

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s