Time Limit:1s Memory Limit:512MByte
Submissions:135Solved:54
5.632
我(或者是在读这篇文字的你)不属于这个世界
这是世界的界限
6.41
世界的意义必定存在于世界之外
世界中的一切事物如其所存在般而存在,如其所发生般而发生
世界之中不存在价值
果然……好女人要有的是,烟、楼顶……还有轻飘飘的衣服呀……
某天,水上由岐看见天上掉下的毛绒玩具。
“被天空接受”那是为了寻找不知何时开始在这个城市流传的“回归天空之路”的行为。
为了被天空接受而被扔出去的木偶,在空中飞舞并最终坠落。
那是为了将其本身即为世界的少女送予天空的少女的行为。
横跨天河的vega与Altair,被称为织女星与牛郎星的两颗星星,再加上北十字星的顶之星deneb,被称为夏季大三角。 那是形容三位一体的圣之图形。
只有夏季大三角在天空闪耀之时,世界才与天空相遇。
我想试一试,第一次,也是最后一次的恶作剧
您正在打galgame,然后突然发现您今天太颓了,于是想写个数据结构题练练手:
说到数据结构,当然要说红黑树啦
有一个红黑树,n个点,然而由于写丑了,所以里面的点权是乱的
红黑树点权当然不能是乱的啊,所以这只是一道题而已,没有让您写红黑树,不用担心
m个操作:
1.询问一条链x -> y中的逆序对对数
2.修改x点的点权为y
所谓逆序对就是说在一个序列中,i < j , a[i] > a[j] 则( i , j )为一个逆序对
1操作可以理解为把x -> y这条链当作一个序列,求这个序列的逆序对对数
![](http://www.ifrog.cc/uploads/2017/1602.png)
思路:
已经提示红黑树的树高是O(logn),那么树高最多也就是20左右。那么如果我们能够找到查询的两点间的路径,那么直接暴力求一下逆序数即可。
先O(n)预处理出来一个Dfs序,那么我们对于查询的两个点u,v,我们从节点1作为根向下根据Dfs序的相关信息,不断的向u的祖先节点走去,直到走到节点u。对于节点v同理,我们从节点1作为根向下根据Dfs序,不断的向v的虚线节点走去,直到走到节点v.
那么我们现在有两条路径,一条是从1到u,另外一条是从1到v.
那么两个路径最后一个重复的位子,就是两个点的LCA.然后将两个序列拼接在一起然后暴力求一下逆序数即可。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
int a[150000];
vector<int >mp[150000];
int cnt,n,m,len1,len2;
int L[150000],R[150000];
int b[100];
int c[100];
int d[100];
void Dfs(int u,int from)
{
L[u]=++cnt;
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
if(v==from)continue;
Dfs(v,u);
}
R[u]=cnt;
}
void Dfs1(int u,int from,int target)
{
b[len1++]=u;
if(u==target)return ;
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
if(v==from)continue;
if(L[v]<=L[target]&&L[target]<=R[v])
{
Dfs1(v,u,target);
}
}
}
void Dfs2(int u,int from,int target)
{
c[len2++]=u;
if(u==target)return ;
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
if(v==from)continue;
if(L[v]<=L[target]&&L[target]<=R[v])
{
Dfs2(v,u,target);
}
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
cnt=0;
for(int i=1;i<=n;i++)mp[i].clear();
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
mp[x].push_back(y);
mp[y].push_back(x);
}
Dfs(1,-1);
for(int i=0;i<m;i++)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
a[x]=y;
}
else
{
len1=0;
len2=0;
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
Dfs1(1,-1,x);
Dfs2(1,-1,y);
/*
for(int j=0;j<len1;j++)printf("%d ",b[j]);
printf("\n");
for(int j=0;j<len2;j++)printf("%d ",c[j]);
printf("\n");*/
int pos=-1;
for(int j=0;j<len1;j++)
{
if(b[j]==c[j])continue;
else
{
pos=j-1;
break;
}
}
if(pos==-1)pos=min(len1-1,len2-1);
int tmp=0;
for(int j=len1-1;j>=pos;j--)
{
d[tmp++]=b[j];
}
for(int j=pos+1;j<len2;j++)
{
d[tmp++]=c[j];
}
int output=0;
for(int j=0;j<tmp;j++)
{
for(int k=0;k<j;k++)
{
if(a[d[k]]>a[d[j]])output++;
}
}
printf("%d\n",output);
}
}
}
}