asd890123 @ 2024-07-25 09:16:11
期望单次复杂度
#include <iostream>
#include <cstring>
namespace GenHelper
{
unsigned z1,z2,z3,z4,b;
unsigned rand_()
{
b=((z1<<6)^z1)>>13;
z1=((z1&4294967294U)<<18)^b;
b=((z2<<2)^z2)>>27;
z2=((z2&4294967288U)<<2)^b;
b=((z3<<13)^z3)>>21;
z3=((z3&4294967280U)<<7)^b;
b=((z4<<3)^z4)>>12;
z4=((z4&4294967168U)<<13)^b;
return (z1^z2^z3^z4);
}
}
void srand(unsigned x)
{using namespace GenHelper;
z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;}
int read()
{
using namespace GenHelper;
int a=rand_()&32767;
int b=rand_()&32767;
return a*32768+b;
}
#define N 20000005
__uint32_t s;
int n,m,a[N],tree[N];
__uint64_t ans = 0;
__always_inline static int lowbit(int x){return x & -x;}
__always_inline static void modify(int x,int y){
for (;x <= n;x += lowbit(x)){
if (tree[x] < y) tree[x] = y;
else break;
}
}
inline static int FindMax(const int &x,const int &y){
if (y > x){
if (y - lowbit(y) > x) return std::max(tree[y],FindMax(x,y - lowbit(y)));
else return std::max(a[y],FindMax(x,y - 1));
}
return a[x];
}
int main(){
#ifndef ONLINE_JUDGE
freopen("P3793.in","r",stdin);
#endif
scanf("%d%d%u",&n,&m,&s);
srand(s);
memset(tree,0x80,sizeof(tree));
for (int i = 1;i <= n;i++) modify(i,a[i] = read());
while (m--){
int l = read() % n + 1,r = read() % n + 1;
if (l > r) std::swap(l,r);
ans += FindMax(l,r);
}
printf("%lu\n",ans);
return 0;
}
by M1saka16I72 @ 2024-07-25 09:55:17
热知识:树状数组维护不可差分信息单次查询的复杂度是
by george0929 @ 2024-08-04 10:11:06
这题要求线性做法(不然为啥数据随机)