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

相关文章

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.