今天的题显然是mhy出的233
t1裸莫队,t3裸平衡树或者堆,t2到现在都还不会,说是什么可持久化trie并且带合并,我好菜啊
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 100000 + 10;
int n, m, block, cnt[ MAXN * 2 ] ;
long long a[ MAXN * 2 ];
struct Q { int l, r, id, blo; long long ans; }q[ MAXN * 2 ];
bool cmp( const Q &a, const Q &b ) {
if( a.blo != b.blo ) return a.blo < b.blo;
if( a.r != b.r ) return a.r < b.r;
return a.l < b.l;
}
void MosAlgorithm( ) {
long long ans = 0;
int l = 1, r = 0;
for( register int i = 1; i <= m; i++ ) {
while( l < q[i].l ) {
cnt[a[l]]--;
if( cnt[a[l]] == 2 ) ans -= 3LL * a[l];
else if( cnt[a[l]] == 1 ) ans += a[l];
else ans -= a[l];
l++;
}
while( l > q[i].l ) {
l--;
cnt[a[l]]++;
if( cnt[a[l]] == 2 ) ans -= a[l];
else if( cnt[a[l]] == 3 ) ans += 3LL * a[l];
else ans += a[l];
}
while( r < q[i].r ) {
r++;
cnt[a[r]]++;
if( cnt[a[r]] == 2 ) ans -= a[r];
else if( cnt[a[r]] == 3 ) ans += 3LL * a[r];
else ans += a[r];
}
while( r > q[i].r ) {
cnt[a[r]]--;
if( cnt[a[r]] == 2 ) ans -= 3LL * a[r];
else if( cnt[a[r]] == 1 ) ans += a[r];
else ans -= a[r];
r--;
}
q[q[i].id].ans = ans;
}
for( register int i = 1; i <= m; i++ ) printf( "%I64d\n", q[i].ans );
}
int main( ) {
scanf( "%d%d", &n, &m ); int block = sqrt(n);
for( register int i = 1; i <= n; i++ ) scanf( "%I64d", &a[i] );
for( register int i = 1; i <= m; i++ ) {
scanf( "%d%d", &q[i].l, &q[i].r );
q[i].id = i;
q[i].blo = ( q[i].l - 1 ) / block + 1;
}
sort( q + 1, q + m + 1, cmp );
MosAlgorithm();
return 0;
}
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
const int mod = 1e9 + 7;
const int MAXN = 1e6 + 10;
int f[MAXN], M[MAXN], a, b, c, d, sz, n;
long long ans;
int root;
struct Tree{ int lson, rson, rnd, sz, wei; int num; }tree[ MAXN * 4 ];
void update( int rt ) { tree[rt].sz = tree[tree[rt].lson].sz + tree[tree[rt].rson].sz + tree[rt].wei; }
void Right_Rotate( int &k ) {
int t = tree[k].lson;
tree[k].lson = tree[t].rson;
tree[t].rson = k;
tree[t].sz = tree[k].sz;
update(k);
k = t;
}
void Left_Rotate( int &k ) {
int t = tree[k].rson;
tree[k].rson = tree[t].lson;
tree[t].lson = k;
tree[t].sz = tree[k].sz;
update(k);
k = t;
}
void insert( int &k, int x ) {
if( k == 0 ) {
k = ++ sz;
tree[k].num = x;
tree[k].rnd = rand();
tree[k].sz = tree[k].wei = 1;
return;
}
tree[k].sz++;
if( x == tree[k].num ){ tree[k].wei++; return; }
else if( x < tree[k].num ) {
insert( tree[k].lson, x );
if( tree[tree[k].lson].rnd < tree[k].rnd ) Right_Rotate(k);
} else {
insert( tree[k].rson, x );
if( tree[tree[k].rson].rnd < tree[k].rnd ) Left_Rotate(k);
}
}
long long find( int k, int rnk ) {
if( rnk >= tree[tree[k].lson].sz + 1 && rnk <= tree[tree[k].lson].sz + tree[k].wei ) return tree[k].num;
else if( rnk <= tree[tree[k].lson].sz ) return find( tree[k].lson, rnk );
else return find( tree[k].rson, rnk - tree[tree[k].lson].sz - tree[k].wei );
}
int main( ) {
scanf( "%d%d%d%d", &a, &b, &c, &n );
f[1] = 1;
insert( root, f[1] ); M[1] = 0;
ans = 1LL;
for( register int i = 2; i <= n; i++ ) {
int kth = ( i - 1 ) / 2;
if( ( i - 1 ) % 2 == 1 ) kth++;
M[i] = find( root, kth );
f[i] = ( 1LL * M[i] * a + b * i + c ) % mod;
ans += 1LL * f[i];
insert( root, f[i] );
}
printf( "%I64d\n", ans );
}
treap要挂掉两个点,没有办法,太慢了,heap会好很多
今天多亏t1写了对拍,要不然就发现不了一个致命错误啦233
如果有哪位dalao愿意赐教t2的,不胜感激233,联系邮箱