【BZOJ1125】[POI2008]Poc hash+map+SBT
【BZOJ1125】[POI2008]Poc
Description
n列火车,每条有l节车厢。每节车厢有一种颜色(用小写字母表示)。有m次车厢交换操作。求:对于每列火车,在交换车厢的某个时刻,与其颜色完全相同的火车最多有多少。
Input
n l m (2 ≤ n ≤ 1000, 1 ≤ l ≤ 100, 0 ≤ m ≤ 100000) n行字符串,长度为l m行,每行4个数a b c d,a车的第b个字符与c车第d个字符交换。
Output
n个数,在交换车厢的某个时刻,与该车颜色完全相同的火车最多数目。
Sample Input
ababbd
abbbbd
aaabad
caabbd
cabaad
2 3 5 4
5 3 5 5
3 5 2 2
1 2 4 3
2 2 5 1
1 1 3 3
4 1 5 6
Sample Output
3
3
2
3
题解:考虑将hash值相同的都放到同一棵平衡树中(可以用map维护平衡树的root)。这样删除和插入都比较容易,每次加入的时候都给平衡树的整体打一个最大值标记即可。
注意a=c的情况。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
typedef unsigned long long ll;
int n,len,m,ret;
char str[1010][110];
struct node
{
int siz,ch[2],tag,org;
}s[1010];
ll bas[110],hs[1010];
int ans[1010];
map<ll,int> rt;
void pushup(int x)
{
s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;
}
void updata(int x,int val) {ans[s[x].org]=max(ans[s[x].org],val),s[x].tag=max(s[x].tag,val);}
void pushdown(int x)
{
if(s[x].tag)
{
if(s[x].ch[0]) updata(s[x].ch[0],s[x].tag);
if(s[x].ch[1]) updata(s[x].ch[1],s[x].tag);
s[x].tag=0;
}
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void rotate(int &x,int d)
{
int y=s[x].ch[d];
pushdown(x),pushdown(y);
s[x].ch[d]=s[y].ch[d^1],s[y].ch[d^1]=x;
pushup(x),pushup(y);
x=y;
}
void maintain(int &x,int d)
{
if(s[s[s[x].ch[d]].ch[d]].siz>s[s[x].ch[d^1]].siz) rotate(x,d);
else if(s[s[s[x].ch[d]].ch[d^1]].siz>s[s[x].ch[d^1]].siz) rotate(s[x].ch[d],d^1),rotate(x,d);
else return ;
maintain(s[x].ch[d],d),maintain(s[x].ch[d^1],d^1);
maintain(x,d),maintain(x,d^1);
}
void insert(int &x,int y)
{
if(!x)
{
x=y,s[x].ch[0]=s[x].ch[1]=0,s[x].siz=1,s[x].tag=0;
return ;
}
pushdown(x);
int d=(s[y].org>s[x].org);
insert(s[x].ch[d],y),s[x].siz++;
maintain(x,d);
}
void del(int &x,int y)
{
s[x].siz--,pushdown(x);
if(y>s[x].org) del(s[x].ch[1],y);
else if(y<s[x].org) del(s[x].ch[0],y);
else
{
if(!s[x].ch[0]||!s[x].ch[1]) ret=x,x=s[x].ch[0]^s[x].ch[1];
else
{
int u=s[x].ch[1]; pushdown(u);
while(s[u].ch[0]) u=s[u].ch[0],pushdown(u);
s[x].org=s[u].org;
del(s[x].ch[1],s[u].org);
}
}
}
int main()
{
n=rd(),len=rd(),m=rd();
int i,j,a,b,c,d,ra,rb;
for(bas[0]=1,i=1;i<=len;i++) bas[i]=bas[i-1]*131;
for(i=1;i<=n;i++)
{
scanf("%s",str[i]+1);
for(j=1;j<=len;j++) hs[i]=hs[i]*131+str[i][j];
s[i].org=i,insert(rt[hs[i]],i),updata(rt[hs[i]],s[rt[hs[i]]].siz);
}
for(i=1;i<=m;i++)
{
a=rd(),b=rd(),c=rd(),d=rd();
if(a==c)
{
del(rt[hs[a]],a),s[ret].org=a;
hs[a]+=(str[a][d]-str[a][b])*bas[len-b];
hs[a]+=(str[a][b]-str[a][d])*bas[len-d];
insert(rt[hs[a]],ret),updata(rt[hs[a]],s[rt[hs[a]]].siz);
swap(str[a][b],str[a][d]);
continue;
}
del(rt[hs[a]],a),s[ret].org=a,ra=ret;
del(rt[hs[c]],c),s[ret].org=c,rb=ret;
hs[a]+=(str[c][d]-str[a][b])*bas[len-b];
hs[c]+=(str[a][b]-str[c][d])*bas[len-d];
insert(rt[hs[a]],ra),updata(rt[hs[a]],s[rt[hs[a]]].siz);
insert(rt[hs[c]],rb),updata(rt[hs[c]],s[rt[hs[c]]].siz);
swap(str[a][b],str[c][d]);
}
for(i=1;i<=n;i++) del(rt[hs[i]],i);
for(i=1;i<=n;i++) printf("%d\n",ans[i]);
return 0;
}//5 6 7 ababbd abbbbd aaabad caabbd cabaad 2 3 5 4 5 3 5 5 3 5 2 2 1 2 4 3 2 2 5 1 1 1 3 3 4 1 5 6
【BZOJ1125】[POI2008]Poc hash+map+SBT的更多相关文章
- 洛谷P3369 【模板】普通平衡树(Treap/SBT)
洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...
- [luogu P3369]【模板】普通平衡树(Treap/SBT)
[luogu P3369][模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删 ...
- 【BZOJ1112】[POI2008]砖块Klo Treap
[BZOJ1112][POI2008]砖块Klo Description N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出 ...
- 【BZOJ1116】[POI2008]CLO 并查集
[BZOJ1116][POI2008]CLO Description Byteotia城市有n个 towns m条双向roads. 每条 road 连接 两个不同的 towns ,没有重复的road. ...
- 【BZOJ1132】[POI2008]Tro 几何
[BZOJ1132][POI2008]Tro Description 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000 Input 第一行给出数字N,N在[3,3000 ...
- AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369
[模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...
- 【BZOJ1124】[POI2008]枪战Maf 贪心+思路题
[BZOJ1124][POI2008]枪战Maf Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开 ...
- 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...
- 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...
随机推荐
- python的__call__、__str__、__repr__、__init__、__class__、__name___、__all__、__doc__、__del__等魔术方法的作用
python中,一切都是对象 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”--魔术方法 1.__call__:作用是把类实例变成一个可调用对象 在Pyth ...
- Java源码阅读Stack
Stack(栈)实现了一个后进先出(LIFO)的数据结构.该类继承了Vector类,是通过调用父类Vector的方法实现基本操作的. Stack共有以下五个操作: put:将元素压入栈顶. pop:弹 ...
- .net平台 基于 XMPP协议的即时消息服务端简单实现
.net平台 基于 XMPP协议的即时消息服务端简单实现 昨天抽空学习了一下XMPP,在网上找了好久,中文的资料太少了所以做这个简单的例子,今天才完成.公司也正在准备开发基于XMPP协议的即时通讯工具 ...
- 用Jmeter对数据库执行压力测试
转载:http://www.cnblogs.com/chengtch/p/6198900.html 在我看来压力测试的压测对象可以分为UI,接口及数据库三个部分吧,对界面及接口进行压测还算熟悉, 定位 ...
- hdu 4865 Peter's Hobby (隐马尔可夫模型 dp)
Peter's Hobby Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
- 怎么以最新汇率牌价计算XX美元相当于多少人民币
http://www.meiguozhuji.com/exchange-rate 美国主机都是以美元来报价的,至于XX美元相当于多少人民币,很多朋友都不太清楚.为了让大家更直接的了解购买美国主机需要花 ...
- 1 android 人脸识别
1 https://www.google.com.hk/search?newwindow=1&safe=strict&q=android+%E5%9B%BE%E7%89%87%E4%B ...
- cache和buffer区别探讨
一. 1.Buffer(缓冲区)是系统两端处理速度平衡(从长时间尺度上看)时使用的.它的引入是为了减小短期内突发I/O的影响,起到流量整形的作用.比如生产者——消费者问题,他们产生和消耗资源的速度大体 ...
- cocos2d-x 3.0 Android环境搭建(亲測通过)
网上一大堆讲述coco2d-x 3.0 版本号的android环境搭建.真是不忍直視.讲的不清不楚,真是不知道他们自己有没有測试过.今天正好忙完项目有点时间去部署了下android环境. cocos2 ...
- Eureka 源码编译安装部署---Eureka运行eureka-server服务
---恢复内容开始--- 折腾了几天,终于运行好了,两个字:佩服 首先感谢这个大佬的博客支持:https://www.cnblogs.com/lifuping/p/5663127.html 1.首先在 ...