• 莫队算法


    题目 http://codeforces.com/contest/617/problem/E

    讲解 https://www.bilibili.com/video/av4291097

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int const N = 100000 + 10;
     5 int const M = 1<<20;  //可能会超出范围
     6 int block;
     7 struct Node
     8 {
     9     int l,r,id;
    10     bool operator < (const Node& e)const{
    11         return l / block < e.l / block || l / block == e.l / block && r < e.r;
    12     }
    13 }q[N];
    14 int n,m;
    15 ll k,a[N];
    16 ll Ans,ans[N],flag[M];
    17 void del(int pos){
    18     flag[a[pos]]--;   
    19     Ans -= flag[a[pos] ^ k];
    20 }
    21 void add(int pos){
    22     Ans += flag[a[pos] ^ k];
    23     flag[a[pos]]++;
    24 }
    25 int main(){
    26     scanf("%d%d%lld",&n,&m,&k);
    27     block = (int)(ceil(pow(n,0.5)));
    28     for(int i=1;i<=n;i++){
    29         scanf("%lld",&a[i]);
    30         a[i] = a[i-1] ^ a[i];
    31     }
    32     for(int i=1;i<=m;i++){
    33         scanf("%d%d",&q[i].l,&q[i].r);
    34         q[i].id = i;
    35     }
    36     sort(q+1,q+1+m);
    37     int L = 1,R = 0;
    38     //flag[0] = 1;
    39     for(int i=1;i<=m;i++){
    40         while(L < q[i].l)    del(L++);//del(L-1),    L++;    
    41         while(L > q[i].l)    add(--L);//L--,    add(L-1);
    42         while(R < q[i].r)    add(++R);//R++,    add(R);
    43         while(R > q[i].r)    del(R--);//del(R--);
    44         //ans[q[i].id] = Ans;
    45         ans[q[i].id] = Ans + flag[k^a[L-1]];
    46     }
    47     for(int i=1;i<=m;i++)
    48         printf("%lld
    ",ans[i]);
    49     return 0;
    50 }
    51 /*
    52 a[l] ^ a[i+1] ^ …… ^a[r] = 
    53 (a[1] ^ a[2] ^ …… ^ a[l-1]) ^ (a[1] ^ a[2] ^ …… ^a[r]) = s[l-1] ^ s[r]
    54 已知区间[l,r]
    55 求区间[l-1,r]为(a[1] ^ a[2] ^ …… ^ a[l-2]) ^ (a[1] ^ a[2] ^ …… ^a[r]) = s[l-2] ^ s[r]
    56 s[l-2] = s[l-1] ^ 
    57 */
    View Code

     题目 https://www.luogu.org/problemnew/show/P2709

    bool cmp(const node &a, const node &b){
        if(a.l/bblock!=b.l/bblock) return a.l/bblock<b.l/bblock;
        return a.r<b.r;
    }
    void update(int pos, int n){
        int val=arr[pos];
        if(n==1) ans=ans+2*cnt[val]+1;
        else ans=ans-2*cnt[val]+1;
        cnt[val]+=n;
    }
    
    for(int io=1; i<=k; i++){
        while(L>node[i].l) update(--L,1);
        while(R<node[i].r) update(++R,1);
        while(L<node[i].l) update(L++,-1);
        while(R>node[i].r) update(R--,-1);
        ans[node[i].id] = ans;
    }
    View Code
  • 相关阅读:
    Oracle86和92语法的连接,子查询,集合的操作
    Oracle笛卡尔积,分组,多表连接
    Oracle排序,伪列,字符函数,数字函数,日期行数
    Oracle基本的数据类型以及简单sql查询
    用while语句打印阶乘
    Switch小练习
    if语句多表达式与一个表达式
    三元操作符
    整数的二进制表达
    与或
  • 原文地址:https://www.cnblogs.com/Kingpenguin/p/10871938.html
Copyright © 2020-2023  润新知