loj517 计算几何瞎暴力

在序列上维护4个操作

1.在序列的尾端添加x

2.输出Al~Ar的和

3.将所有数异或x

4.将序列从小到大排序

第一眼看上去是Splay于是头铁硬刚了一发

后来发现splay没法异或

去百度“维护异或  数据结构”

然后看到了Trie树  学习了一个

1.直接插到序列里

2.考虑前缀和  因为Trie树所管辖的下标区间是有序的,所以这里相当于求Trie树中最小的x个数的,记一下每个点下面数字个数(sz)就可以了

3.考虑整体打一个xortag 对于当前存在的xortag 我们将它的每一位分解到Trie树上跑,如果xortag某一位为1,那么其实相当于该位置的左儿子比右儿子大 处理一下即可

4.把序列插到Trie树里

然后瞎暴力/滑稽

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#define ll long long
#define pi 3.14
#define eps 1e-9
#define INF 2147483233
#define m(a) memset(a,0,sizeof(a))
#define M(a) memset(a,127,sizeof(a))
#define REP(i,m,n) for(int i=1;i<=n;i++)
#define DWN(i,n,m) for(int i=n;i>=1;i++)
#define lowbit(x) x&(-x)
#define POJ(n) while(~scanf("%d",&n) && n)
using namespace std;
const int maxn=1e5,maxh=30;
int xortag,n,m;
struct trie
{
    int ch[maxn*maxh][2];
    int sz[maxn*maxh];
    int sum[maxn*maxh][maxh];
    int root=0;
    int len=0;
    int tag=0;
    void insert(int x)
    {
        int u=root;
        for(int i=maxh-1;i>=0;--i)
        {
            int id=((x&(1<<i))>0);
            if(!ch[u][id]) ch[u][id]=++len;
            u=ch[u][id];
            ++sz[u];
            for(int j=0;j<maxh;++j)
                if(x&(1<<j)) sum[u][j]++;
        }
    }
    long long getsum(int x)
    {
        long long ans=0;
        for(int i=0;i<maxh;++i)
            if(xortag&(1<<i)) ans+=(sz[x]-sum[x][i])*(1LL<<i);else ans+=sum[x][i]*(1LL<<i);
        return ans;
    }
    long long query(int x)
    {
        if(x==0) return 0;
        int u=root;
        long long ans=0;
        for(int i=maxh-1;i>=0;--i)
        {
            int l=0,r=1;
            if(tag&(1<<i)) swap(l,r);
            if(x<=sz[ch[u][l]]) u=ch[u][l];
            else
            {
                ans+=getsum(ch[u][l]);
                x-=sz[ch[u][l]];
                u=ch[u][r];
            }
        }
        ans+=getsum(u)/sz[u]*x;
        return ans;
    }
    int getsize()
    {
        return sz[ch[root][0]]+sz[ch[root][1]];
    }
}Trie;
struct array
{
    int a[maxn+50];
    int sum[maxn+50][maxh];
    int len=0;
    void insert(int x)
    {
        x^=xortag;
        a[++len]=x;
        for(int i=0;i<maxh;++i)
            sum[len][i]=sum[len-1][i]+((x&(1<<i))>0);
    }
    long long query(int x)
    {
        long long ans=0;
        for(int i=0;i<maxh;++i)
            if(xortag&(1<<i)) ans+=(x-sum[x][i])*(1LL<<i);else ans+=sum[x][i]*(1LL<<i);
        return ans;
    }
    void transfer()
    {
        Trie.tag=xortag;
        for(int i=1;i<=len;++i)
            Trie.insert(a[i]);
        len=0;
    }
}Array;
long long query(int x)
{
    if(x<=Trie.getsize()) return Trie.query(x);
    else return Trie.query(Trie.getsize())+
        Array.query(x-Trie.getsize());
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        int x;
        scanf("%d",&x);
        Array.insert(x);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i)
    {
        int op,x,y;
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d",&x);
            Array.insert(x);
        }
        if(op==2)
        {
            scanf("%d%d",&x,&y);
            printf("%lld\n",query(y)-query(x-1));
        }
        if(op==3)
        {
            scanf("%d",&x);
            xortag^=x;
        }
        if(op==4) Array.transfer();
    }
    return 0;
}
时间: 2024-11-25 00:36:14

loj517 计算几何瞎暴力的相关文章

汕头市队赛 SRM14 T1 计算几何瞎暴力

计算几何瞎暴力 (easy.pas/c/cpp) 128MB 1s 在平面上,给定起点和终点,有一面墙(看作线段)不能穿过,问从起点走到终点的最短路程. 输入格式 输入一行,包含8个用空格分隔的整数xS,yS,xT,yT,x1,y1,x2,y2,依次表示起点(xS,yS),终点(xT,yT),线段(x1,y1)-(x2,y2). 输出格式 输出一个整数,表示答案四舍五入到整数后的值,保证答案精确值的小数点后一位不是4或5. 样例输入 1 1 2 2 1 2 2 1 样例输出 2 样例解释 走折线

LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力

二次联通门 : LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 /* LibreOJ #517. 「LibreOJ β Round #2」计算几何瞎暴力 叫做计算几何 实则毒瘤数据结构 看到xor后 考虑Trie树 Trie树的每一个节点保存的是以当前子树中每个二进制位的个数 给Trie打一个全局xor标记,如果标记这一位是1,就交换它的两个儿子 另外维护一个前缀和 前缀和存的是没sort过的值的和 Trie维护的是sort之后的值 1操作直接在前缀和后加就好

HDU 5533 Dancing Stars on Me 计算几何瞎暴力

Dancing Stars on Me Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1184    Accepted Submission(s): 651 Problem Description The sky was brushed clean by the wind and the stars were cold in a b

玲珑杯 round18 A 计算几何瞎暴力

题目链接 : http://www.ifrog.cc/acm/problem/1143 当时没看到坐标的数据范围= =看到讨论才意识到,不同的坐标最多只有1k多个,完全可以暴力做法,不过也要一些技巧. 首先注意数很大可能爆int,用LL得话注意强制转换或者全设为LL,假如  int a=50000,b=a;  LL sum=a*b; 则会爆出,除非ab都是LL 或者 sum=(LL)a*(LL)b; 还有就是R最大就是30,我们不妨设ans[i]表示R<=i的组合个数,做一个前缀和方便快速询问.

「LibreOJ β Round #2」计算几何瞎暴力

https://loj.ac/problem/517 题解 首先我们如果没有排序这个骚操作的话,可以直接记一下各个数位的前缀和,然后异或标记给全局打,查询的时候先把区间信息提取出来然后整体异或就好了. 对于排序,我们考虑对所有排好序的节点建\(trie\)树,这样即使有全局异或标记,我们也可以在\(trie\)树上完成前缀信息的查询. 然后就做完了. 代码 #include<bits/stdc++.h> #define N 200009 #define ls ch[cnt][0] #defin

“玲珑杯”ACM比赛 Round #18 A 计算几何你瞎暴力(瞎暴力)

题目链接:http://www.ifrog.cc/acm/problem/1143 题意:如果从一个坐标为 (x1,y1,z1)(x1,y1,z1)的教室走到(x2,y2,z2)(x2,y2,z2)的距离为 |x1−x2|+|y1−y2|+|z1−z2| 那么有多少对教室之间的距离是不超过R的呢? 题解:暴力暴力,把点记录在三维数组里面,然后暴力搜寻符合条件的点,值得注意的是在同个位置可能有不同的教室(明显不符合现实,蜜汁尴尬(逃.....) 不同位置直接暴力,会重复计算一次,比如点(1,2,3

Gym 101055A 计算几何,暴力

http://codeforces.com/gym/101055/problem/A 题目:给定一些三维空间的点,要你找一个平面,能覆盖尽量多的点,只要求输出点数即可.n<=50 因为数据量小,我们考虑暴力. 首先,三个不在同一条直线的点,确定一个平面,然后枚举其他的点.判断一下,这样的复杂度是n^4.可以接受 特判.所有点都在同一条直线.直接输出n. 后面的,枚举三个点后,能算出这个平面的法向量,然后枚举其他点,与法向量的数量积是0的,就可以ans++ #include <cstdio>

暴力枚举法总结

集训快要结束了,按照要求需要写一篇关于枚举的总结,于是在网上也看了许多其他菊苣写的文章,深受启发,但是思来想去感觉又不太系统,于是希望能在吸收那些知识后做一些整理,帮助后面的新人. 枚举的基本方法: 枚举,枚举,顾名思义,就是将所有情况都举出,并判断其是否符合题目条件.所以枚举的基本方法便是分析题意后,找到一个合适的维度列举每一个元素,以完成题目.其中如何找到一个合适的维度来进行枚举便是其中的最大难点. 枚举的基本条件: 首先是时间条件.一般来说主流的OJ当中,1000ms的时间限制下可以运行操

UVa12304(计算几何中圆的基本操作)

断断续续写了250多行的模拟,其间被其他事情打扰,总共花了一天才AC吧~ 这道题目再次让我明白,有些事情看起来很难,实际上并没有我们想象中的那么难.当然了我主要指的不是这个题的难度-- 也是初学计算几何,然后居然胆大妄为地不用刘汝佳的思路去实现这些个功能,其中有三个功能是我用自己的思路实现的吧(瞎暴力),最后果然也是自己写的出锅了. 当一个贼长的模拟题交上去一发WA时,我是欲哭无泪的--这让我怎么debug--只好不断安慰自己要用计算几何题去练习耐心. 只是没想到在不断的固执与冷静的试探之下,不