codeforces 438D

在某位不知名的大大推荐下做了这题,和我上一篇的线段树很像,于是怒拍,思想基本相同,记录区间最大值,当最大值小于取模时可以剪枝。
今后再遇到此类问题算是能解决了
// file name: d.cpp                               //
// author: huangjipeng                               //
// creat time: 2014年05月26日 星期一 16时40分18秒    //
///////////////////////////////////////////////////////
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 100005
struct node
{
	int l,r;
	int mid;
	long long maxx;
	long long sum;
}tree[MAXN<<2];
void build(int l,int r,int now)
{
	tree[now].l=l;
	tree[now].r=r;
	tree[now].mid=(l+r)>>1;
	if(l==r)
	{
		scanf("%I64d",&tree[now].maxx);
		tree[now].sum=tree[now].maxx;
		return ;
	}
	build(l,tree[now].mid,now<<1);
	build(tree[now].mid+1,r,now<<1|1);
	tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum);
	tree[now].maxx=max(tree[now<<1].maxx,tree[now<<1|1].maxx);
}
long long query(int l,int r,int now)
{
	if(tree[now].l==l && tree[now].r==r)
		return tree[now].sum;
	if(l>tree[now].mid)
		return query(l,r,now<<1|1);
	else if(r<=tree[now].mid)
		return query(l,r,now<<1);
	else
		return query(l,tree[now].mid,now<<1)+query(tree[now].mid+1,r,now<<1|1);
}
void update(int l,int r,long long x,int now)
{
	if(tree[now].maxx<x)
		return ;
	if(tree[now].l==tree[now].r)
	{
		tree[now].sum=tree[now].sum%x;
		tree[now].maxx=tree[now].sum;
		return ;
	}
	if(l>tree[now].mid)
		update(l,r,x,now<<1|1);
	else if(r<=tree[now].mid)
		update(l,r,x,now<<1);
	else
	{
		update(l,tree[now].mid,x,now<<1);
		update(tree[now].mid+1,r,x,now<<1|1);
	}
	tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
	tree[now].maxx=max(tree[now<<1].maxx,tree[now<<1|1].maxx);
}
void op3(int k,long long x,int now)
{
	if(tree[now].l==k && tree[now].r==k)
	{
		tree[now].maxx=tree[now].sum=x;
		return ;
	}
	if(k>tree[now].mid)
		op3(k,x,now<<1|1);
	else
		op3(k,x,now<<1);
	tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum);
	tree[now].maxx=max(tree[now<<1].maxx,tree[now<<1|1].maxx);
}
int main()
{
	int n,m;
	cin>>n>>m;
	build(1,n,1);
	while(m--)
	{
		int op;
		scanf("%d",&op);
		if(op==1)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			cout<<query(l,r,1)<<endl;
		}
		else if(op==2)
		{
			int l,r;
			long long x;
			scanf("%d%d%I64d",&l,&r,&x);
			update(l,r,x,1);
		}
		else if(op==3)
		{
			int k;
			long long x;
			scanf("%d%I64d",&k,&x);
			op3(k,x,1);
		}
	}
    return 0;
}

codeforces 438D

时间: 2024-08-01 19:32:25

codeforces 438D的相关文章

CodeForces 438D The Child and Sequence(线段树)

题目:http://codeforces.com/problemset/problem/438/D 一个数取模n%m,有两种情况. 1.m>n, n%m=n; 2.m<=n, n%m<=n/2; 所以当m>n时,取模操作可以忽略. 每个a[i]最多需要log(a[i])次取模操作变为0,因此我们可以对所有取模进行暴力更新.最多要更新n*log(a[i])次,由于单次更新复杂度为log(n),所以总复杂度为n*logn*log(a[i]). #include <bits/std

【CodeForces 438D 】The Child and Sequence

题意 要求支持三种操作  1.区间求和  2.单点修改  3.区间取模 分析 问题主要在于区间取模 需要多维护一个区间最大值,当最大值已经小于模数的时候就不需要操作了 [先开始读错题了,写了个区间修改哎我没救了] #include<bits/stdc++.h> using namespace std; #define N 110000 #define ll long long #define lc (p<<1) #define rc (p<<1|1) #define m

Codeforce 水题报告(2)

又水了一发Codeforce ,这次继续发发题解顺便给自己PKUSC攒攒人品吧 CodeForces 438C:The Child and Polygon: 描述:给出一个多边形,求三角剖分的方案数(n<=200). 首先很明显可能是区间dp,我们可以记f[i][j]为从i到j的这个多边形的三角剖分数,那么f[i][j]=f[i][k]*f[j][k]*(i,j,k是否为1个合格的三角形) CodeForces 438D:The Child and Sequence 描述:给一个序列,要求支持区

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp