Submission #382273

#TimeUsernameProblemLanguageResultExecution timeMemory
382273BartolMIntergalactic ship (IZhO19_xorsum)C++17
100 / 100
647 ms17000 KiB
#include <bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <int, pii> pip;
typedef pair <pii, int> ppi;
typedef pair <ll, ll> pll;

const int INF=0x3f3f3f3f;
const int LOG=7;
const int N=1005;
const int MOD=1e9+7;
const int Q=1e5+5;

int add(int a, int b) {
    a+=b;
    if (a>=MOD) a-=MOD;
    return a;
}

int mul(int a, int b) {
    return (ll)a*b%MOD;
}

int n, q;
int p[N], pot[Q], uk1[N], uk2[N], isti[N], sweep[N];
vector <pii> vec[LOG], v[LOG][LOG];
vector <int> que[N];
#define DEBUG 0

int solve(int bit1, int bit2) {
    int sol=0;
    for (pii pp:vec[bit1]) uk1[pp.X]++, uk1[pp.Y+1]--;
    for (pii pp:vec[bit2]) uk2[pp.X]++, uk2[pp.Y+1]--;
    for (pii pp:v[bit1][bit2]) que[pp.X].pb(pp.Y);

    for (int i=1; i<n; ++i) uk1[i]+=uk1[i-1], uk2[i]+=uk2[i-1];


    for (int i=0; i<n; ++i) {
        for (int j=i; j<n; ++j) sweep[j]=0;
        for (int r:que[i]) sweep[r]++;
        for (int j=n-1; j>=i; j--) {
            sweep[j]+=sweep[j+1];
            isti[j]+=sweep[j];
        }
        int curr_bit=!!(p[i] & (1<<bit1));

        for (int j=i; j<n; ++j) {

            int interi=mul(i+1, n-j);
            int komb_i=curr_bit, komb_j=!!(p[j] & (1<<bit2));
            int unija=uk1[i]+uk2[j]-isti[j];
            int curr=1;

            if (i!=j) interi=mul(interi, 2);
            else if (bit1==bit2) {
                curr=mul(pot[q-unija], isti[j] ? pot[isti[j]-1] : curr_bit);
                sol=add(sol, mul(curr, interi));
                #if DEBUG
                    printf("1. slucaj, curr: %d, interi: %d\n", curr, interi);
                #endif
                continue;
            }



            if (uk1[i]>isti[j]) {
                komb_i=pot[uk1[i]-isti[j]-1];
                if (uk2[j]>isti[j]) curr=mul(pot[isti[j]], mul(pot[uk2[j]-isti[j]-1], komb_i));
                else curr=mul(isti[j] ? pot[isti[j]-1] : komb_j, komb_i);
            }
            else {
                if (uk2[j]>isti[j]) curr=mul(isti[j] ? pot[isti[j]-1] : komb_i, pot[uk2[j]-isti[j]-1]);
                else if (isti[j]) curr=mul(pot[isti[j]-1], !(komb_i^komb_j));
                else curr=komb_i==komb_j && komb_i==1;
            }
            curr=mul(curr, pot[q-unija]);
            #if DEBUG
                printf("i: %d, j: %d, isti: %d\n", i, j, isti[j]);
                printf("uk1: %d, uk2: %d, unija: %d, preostali: %d\n", uk1[i], uk2[j], unija, q-unija);
                printf("interi: %d, curr: %d\n\n", interi, curr);
            #endif
            sol=add(sol, mul(curr, interi));
        }
    }
    #if DEBUG
        printf("bit1: %d, bit2: %d, sol == %d\n", bit1, bit2, sol);
    #endif // DEBUG
    return sol;
}

void reset() {
    for (int i=0; i<n; ++i) que[i].clear();
    memset(uk1, 0, sizeof uk1);
    memset(uk2, 0, sizeof uk2);
    memset(isti, 0, sizeof isti);
}

void load() {
    scanf("%d", &n);
    for (int i=0; i<n; ++i) scanf("%d", p+i);
    scanf("%d", &q);
    for (int i=0; i<q; ++i) {
        int l, r, x;
        scanf("%d %d %d", &l, &r, &x); l--; r--;
        for (int i=0; i<LOG; ++i) {
            if ((1<<i) & x) vec[i].pb(mp(l, r));
            else continue;
            for (int j=0; j<LOG; ++j) {
                if ((1<<j) & x) v[i][j].pb(mp(l, r));
            }
        }
    }
}

int main() {

    load();

    pot[0]=1;
    for (int i=1; i<=q; ++i) pot[i]=mul(pot[i-1], 2);

    int sol=0;
    for (int i=0; i<LOG; ++i) {
        for (int j=0; j<LOG; ++j) {
            reset();
            int br=mul((1<<i), (1<<j));
            sol=add(sol, mul(solve(i, j), br));
        }
    }
    printf("%d\n", sol);
    return 0;
}

/*
2
3 1
2
2 2 2
1 2 0

2
1 1
1
1 2 3

*/

Compilation message (stderr)

xorsum.cpp: In function 'void load()':
xorsum.cpp:107:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  107 |     scanf("%d", &n);
      |     ~~~~~^~~~~~~~~~
xorsum.cpp:108:34: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  108 |     for (int i=0; i<n; ++i) scanf("%d", p+i);
      |                             ~~~~~^~~~~~~~~~~
xorsum.cpp:109:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  109 |     scanf("%d", &q);
      |     ~~~~~^~~~~~~~~~
xorsum.cpp:112:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  112 |         scanf("%d %d %d", &l, &r, &x); l--; r--;
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...