您的位置:首页 > 其它

hdu 5634 Rikka with Phi

2018-02-01 00:40 302 查看
题意:完成三种操作

There are three types of queries: 

1lr 

Change A[i] into φ(A[i]),
for all i∈[l,r].

2lrx 

Change A[i] into x,
for all i∈[l,r].

3lr 

Sum up A[i],
for all i∈[l,r].

题解:线段树+欧拉函数

代码

#include<cstdio>
#include<cstring>
#define M 300100
#define N 10000100
#define ll long long

ll sum[M * 4];
int a[M * 4];
int phi
;
int prime
;

void build(int node, int l, int r)
{
if(l == r)
{
scanf("%d", &a[node]);
sum[node] = a[node];
return;
}
int mid = (l + r) / 2;
build(node * 2 ,l, mid);
build(node * 2 + 1, mid + 1, r);
sum[node] = sum[node * 2] + sum[node * 2 + 1];
if(a[node * 2] == a[node * 2 + 1])
a[node] = a[node * 2];
else a[node] = 0;
}

void updata1(int l, int r, int left, int right, int node)
{
if(left <= l && right >= r && a[node])
{
a[node] = phi[a[node]];
sum[node] = (ll)(r - l + 1) * a[node];
return;
}
if(l == r)
{
a[node] = phi[sum[node]];
sum[node] = phi[sum[node]];
return;
}
if(a[node])
{
int mid = (l + r) / 2;
sum[node * 2] = (ll)(mid - l + 1) * a[node];
sum[node * 2 + 1] = (ll)(r - mid) * a[node];
a[node * 2] = a[node];
a[node * 2 + 1] = a[node];
a[node] = 0;
}
int mid = (l + r) / 2;
if(left <= mid)updata1(l, mid, left, right, node * 2);
if(right > mid)updata1(mid + 1, r, left, right, node * 2 + 1);
sum[node] = sum[node * 2] + sum[node * 2 + 1];
if(a[node * 2] == a[node * 2 + 1])
a[node] = a[node * 2];
else a[node] = 0;
}

void updata2(int l, int r, int left, int right, int node, int x)
{
if(left <= l && right >= r)
{
a[node] = x;
sum[node] = (ll)x * (r - l + 1);
return;
}
if(a[node])
{
int mid = (l + r) / 2;
sum[node * 2] = (ll)(mid - l + 1) * a[node];
sum[node * 2 + 1] = (ll)(r - mid) * a[node];
a[node * 2] = a[node];
a[node * 2 + 1] = a[node];
a[node] = 0;
}
int mid = (l + r) / 2;
if(left <= mid)updata2(l, mid, left, right, node * 2, x);
if(right > mid)updata2(mid + 1, r, left, right, node * 2 + 1, x);
sum[node] = sum[node * 2] + sum[node * 2 + 1];
if(a[node * 2] == a[node * 2 + 1])
a[node] = a[node * 2];
else a[node] = 0;
}

ll query(int l, int r, int left, int right, int node)
{
if(left <= l && right >= r)
return sum[node];
if(a[node])
{
int mid = (l + r) / 2;
sum[node * 2] = (ll)(mid - l + 1) * a[node];
sum[node * 2 + 1] = (ll)(r - mid) * a[node];
a[node * 2] = a[node];
a[node * 2 + 1] = a[node];
a[node] = 0;
}
ll ans = 0;
int mid = (l + r) / 2;
if(left <= mid)ans = ans + query(l, mid, left, right, node * 2);
if(right > mid)ans = ans + query(mid + 1, r, left, right, node * 2 + 1);
return ans;
}

void phi_table()
{
memset(phi,0,sizeof(phi));
phi[1]=1;
int flag = 0;
for(int i=2;i<=N;i++)
{
if(!phi[i])phi[i]=i-1,prime[flag++]=i;
for(int j=0;j < flag&&prime[j]*i<=N;j++)
{
if(i%prime[j]) phi[prime[j]*i] = phi[i]*(prime[j]-1);
else
{
phi[prime[j]*i] = phi[i]*prime[j];
break;
}
}
}
}

int main()
{
phi_table();
int T;
scanf("%d", &T);
for(int t = 1; t <= T; t++)
{
int n, m;
scanf("%d %d", &n, &m);
build(1, 1, n);
for(int i = 1; i <= m; i++)
{
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
if(x == 1)updata1(1, n, y, z, 1);
else if(x == 2)
{
int num;
scanf("%d", &num);
updata2(1, n, y, z, 1,num);
}
else if(x == 3)
printf("%lld\n", query(1, n, y, z, 1));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: