Squared Permutation

Time Limit: 6000ms
Memory Limit: 262144KB

64-bit integer IO format: %lld      Java class name: Main

最近,无聊的过河船同学在玩一种奇怪的名为“小Q的恶作剧”的纸牌游戏。

现在过河船同学手有张牌,分别写着,打乱顺序之后排成一行,位置从左往右按照标号。

接下来小Q同学会给出个操作,分为以下两种:

1.给定,交换从左往右数的第和第张牌,

2.给定,对从左往右数的第张牌,记下位置是这张牌上的数字的牌的数字,询问所有记下的数字加起来的结果。

虽然无聊的过河船同学精通四则运算,但是要完成这么大的计算量还是太辛苦了,希望你能帮他处理这些操作。

 

Input

第一行是一个正整数,表示测试数据的组数,

对于每组测试数据,

第一行是一个整数

第二行包含一个的排列,其中第个数表示第张牌上的数字,

第三行是一个整数,表示操作数,

接下来行,每行包含三个整数,其中表示操作的类型。

 

Output

对于每组测试数据,依次输出所有查询操作的结果,每个结果一行。

 

Sample Input

1
3
1 2 3
3
2 1 2
1 1 3
2 2 3

Sample Output

3
5

Hint

对于样例,

第二次操作后牌上的数字从左往右依次是3,2,1,

第三次操作的结果是位置是第2张牌上的数字的牌的数字加上位置是第3张牌上的数字的牌的数字,也就是第2张牌上的数字加上第1张牌上的数字,结果是5。

 

Source

思路:很显然用线段树,但是发现线段树在更新两点会有后效;
   最多更新四个点;注意的是先更新flag数组;
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#include<stack>
#include<cstring>
#include<vector>
#include<list>
#include<set>
#include<map>
using namespace std;
#define ll long long
#define mod 1000000007
#define inf 999999999
int scan()
{
int res = , ch ;
while( !( ( ch = getchar() ) >= '' && ch <= '' ) )
{
if( ch == EOF ) return << ;
}
res = ch - '' ;
while( ( ch = getchar() ) >= '' && ch <= '' )
res = res * + ( ch - '' ) ;
return res ;
}
//#pragma comment(linker, "/STACK:102400000,102400000")
ll a[],flag[];
struct is
{
ll l,r;
ll sum;
}tree[*];
void buildtree(ll l,ll r,ll pos)
{
tree[pos].l=l;
tree[pos].r=r;
if(l==r)
{
tree[pos].sum=a[a[l]];
return;
}
ll mid=(l+r)/;
buildtree(l,mid,pos*);
buildtree(mid+,r,pos*+);
tree[pos].sum=tree[pos*].sum+tree[pos*+].sum;
}
void update(ll point,ll change,ll pos)
{
if(tree[pos].l==point&&tree[pos].r==point)
{
tree[pos].sum=change;
return;
}
ll mid=(tree[pos].l+tree[pos].r)/;
if(point<=mid)
update(point,change,pos*);
else
update(point,change,pos*+);
tree[pos].sum=tree[pos*].sum+tree[pos*+].sum;
}
ll query(ll l,ll r,ll pos)
{
if(tree[pos].l==l&&tree[pos].r==r)
{
return tree[pos].sum;
}
ll mid=(tree[pos].l+tree[pos].r)/;
if(mid>=r)
return query(l,r,pos*);
else if(mid<l)
return query(l,r,pos*+);
else
return query(l,mid,pos*)+query(mid+,r,pos*+);
}
int main()
{
ll x,y,z,i,t;
int gg;
scanf("%d",&gg);
while(gg--)
{
scanf("%lld",&x);
for(i=;i<=x;i++)
{
scanf("%lld",&a[i]);
flag[a[i]]=i;
}
buildtree(,x,);
scanf("%lld",&y);
while(y--)
{
ll op,l,r;
scanf("%lld%lld%lld",&op,&l,&r);
if(op==)
{
ll hh=query(l,l,);
ll kk=query(r,r,);
ll hhh=query(flag[l],flag[l],);
ll kkk=query(flag[r],flag[r],);
update(l,kk,);
update(r,hh,);
flag[a[l]]=r;
flag[a[r]]=l;
update(flag[l],kkk,);
update(flag[r],hhh,);
swap(a[l],a[r]);
/*for(i=1;i<=x;i++)
cout<<a[i]<<" ";
cout<<endl;
for(i=1;i<=x;i++)
cout<<flag[i]<<" ";
cout<<endl;
for(i=1;i<=x;i++)
cout<<query(i,i,1)<<" ";
cout<<endl;*/
}
else
{
printf("%lld\n",query(l,r,));
}
}
}
return ;
}

bnu 51636 Squared Permutation 线段树的更多相关文章

  1. BNU 2418 Ultra-QuickSort (线段树求逆序对)

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=2418 解题报告:就是给你n个数,然后让你求这个数列的逆序对是多少?题目中n的范围是n & ...

  2. UVaLive 11525 Permutation (线段树)

    题意:有一个由1到k组成的序列,最小是1 2 … k,最大是 k k-1 … 1,给出n的计算方式,n = s0 * (k - 1)! + s1 * (k - 2)! +… + sk-1 * 0!, ...

  3. CF798E. Mike and code of a permutation [拓扑排序 线段树]

    CF798E. Mike and code of a permutation 题意: 排列p,编码了一个序列a.对于每个i,找到第一个\(p_j > p_i\)并且未被标记的j,标记这个j并\( ...

  4. MemSQL Start[c]UP 2.0 - Round 1 F - Permutation 思维+线段树维护hash值

    F - Permutation 思路:对于当前的值x, 只需要知道x + k, x - k这两个值是否出现在其左右两侧,又因为每个值只有一个, 所以可以转换成,x+k, x-k在到x所在位置的时候是否 ...

  5. Permutation UVA - 11525(值域树状数组,树状数组区间第k大(离线),log方,log)(值域线段树第k大)

    Permutation UVA - 11525 看康托展开 题目给出的式子(n=s[1]*(k-1)!+s[2]*(k-2)!+...+s[k]*0!)非常像逆康托展开(将n个数的所有排列按字典序排序 ...

  6. D. Restore Permutation(权值线段树)

    D. Restore Permutation time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  7. [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和)

    [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和) E. Permuta ...

  8. BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】

    A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. O ...

  9. UVA 11525 Permutation ——(线段树,脑筋急转弯)

    只要注意到对于譬如:S1*(k-1)! 因为后面k-1个数字的全排列个数刚好是(k-1)!,那么第一个数字就是没有取过的数字的第(S1+1)个即可.取走这个数字以后这个数字就不能再用了,依次类推即可得 ...

随机推荐

  1. bootstrap modal插件弹出窗口如何限制最大高度,并且在内容过多时可以滚动显示

    .modal-body{ max-height:400px; overflow-y:auto; } 只有在modal-body类上限制高度才能起作用,其他地方的限制均不起作用

  2. PAT 1015 Reversible Primes[求d进制下的逆][简单]

    1015 Reversible Primes (20)(20 分)提问 A reversible prime in any number system is a prime whose "r ...

  3. ID和Name

    ID和Name都可以用来标识一个标记,Javascript分别有两个方法getElementById和getElementByName来定位Dom节点. 区别如下: 1.我们知道在网页做Post提交时 ...

  4. Python qq企业邮箱发送邮件

    Python qq企业邮箱发送邮件 进入客户端设置: 下面是代码部分: from email.header import Header from email.mime.text import MIME ...

  5. Summary: Binary Search

    Iterative ways: int binarySearch (int[] a, int x) { int low = 0; int high = a.length - 1; int mid; w ...

  6. Dapper Extensions中修改Dialect

    如果是MySql数据库,则修改为:DapperExtensions.DapperExtensions.SqlDialect = new MySqlDialect(); DapperExtensions ...

  7. volatile的语义与实现

    1.volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修 ...

  8. 更换mysql数据库的datadir目录

    更换过程如下: 1.新建指定的datadir目录,这里举例如:E:/mysql_datadir/data. 2.关闭mysql57服务器. 3.将原来的datadir目录下面的所有文件拷贝到E:/my ...

  9. FRM-40212: Invalid value for field %s.

    Cause:        Caused by one of the following: 1.  The value is not of the proper data type. 字段类型不对 2 ...

  10. python pip list 命令列出所有安装包和版本信息

    c:\Python27\Scripts>pip listDEPRECATION: The default format will switch to columns in the future. ...