Codeforces Round #352 div1 C D (智商+线段树)

原创 2016年05月30日 20:17:32


Ultimate Weirdness of an Array

题意:给一个数列ai, f(i,j) 定义为除去i到j之间的数后最大gcd(ai, aj)的值, 求所有f(i,j)之和



#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <bitset>
#include <queue>
#include <set>	
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;

#define LL long long
#define ULL unsigned long long
#define eps 1e-9
#define N (200000+ 10)
#define M (10000000 + 10)
#define pii pair<int,int>
#define MP make_pair
#define inf 0x3f3f3f3f
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define ls (i<<1)
#define rs (i<<1|1)
#define mod 9973


int a[N];
int l1[N], l2[N], r1[N], r2[N];

void mark(int j, int i) {
	if(!l1[j]) l1[j] = i;
	else if(!l2[j]) l2[j] = i;
	r2[j] = r1[j];
	r1[j] = i;
}

int mx[N<<2], mi[N<<2];
LL b[N],s[N<<2];
int c[N<<2];
void update(int l, int r, int v, int ll, int rr, int i) {
	if(l > r) return ;
	if(mi[i] >= v) return ;
	if(ll == rr) {
		mx[i] = max(mx[i], v);
		mi[i] = mx[i];
		s[i] = mx[i];
		return ;
	}
	if(ll == l && r ==  rr && mx[i] <= v) {
		mx[i] = mi[i] = v;
		s[i] = (LL)v * (rr-ll+1);
		c[i] = v;
		return ;
	}
	if(c[i]) {
		int len = rr-ll+1;
		c[ls] = c[i], c[rs] = c[i];
		mi[ls] = mx[ls] = c[i], mi[rs] = mx[rs] =c[i];
		s[ls] = (LL)(len-len/2) * c[i], s[rs] = (LL)len/2 * c[i];
		c[i] = 0;
	}
	int md = ll+rr>> 1;
	if(r <= md) update(l, r, v, lson);
	else if(l > md) update(l, r, v, rson);
	else update(l, md, v, lson), update(md+1, r, v, rson);
	mx[i] = max(mx[ls], mx[rs]);
	mi[i] = min(mi[ls], mi[rs]);
	s[i] = s[ls] + s[rs];
}


int main() {
	//freopen("in.txt", "r", stdin);
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
	for(int i = 1; i <= n; ++i) {
		int y = (int)sqrt(a[i] *1.0);
		for(int j = 1; j <= y; ++j) {
			if(a[i] % j == 0) {
				mark(j, i);
				if(j * j != a[i]) 
					mark(a[i]/j, i);
			}
		}
	}
	for(int i = 1; i <= n; ++i) update(i, i, i, 1, n, 1);
	int Max = 200005;
	for(int i = Max; i >= 1; --i) {
		if(l1[i] != r1[i]) {
			update(1, l1[i], r2[i], 1, n, 1);
			update(l1[i]+1, l2[i], r1[i], 1, n, 1);
			update(l2[i]+1, n, n+1, 1, n, 1);
		}
		b[i] = (LL)n*(n+1) - s[1];

		
	}	
	LL ans = 0;
	for(int i = 1; i < Max; ++i)
		ans += (b[i+1]-b[i]) * i;
	printf("%I64d\n", ans);
}

Roads in Yusland


题意:给一个有根树,m条路径u,v,费用为ci,v是u的祖先,选取一些路径覆盖树上所有边


#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <bitset>
#include <queue>
#include <set>	
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;

#define LL long long
#define ULL unsigned long long
#define eps 1e-9
#define N (300000+ 10)
#define M (1000000 + 10)
#define pii pair<int,int>
#define MP make_pair
#define md (ll+rr>>1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define ls (i<<1)
#define rs (i<<1|1)
#define mod 9973

const LL inf = (LL) 1e15;
int fst[N], vv[M], nxt[M], e;

void init() {
	memset(fst, -1, sizeof fst);
	e = 0;
}

void add(int u, int v) {
	vv[e] =v, nxt[e] = fst[u], fst[u] = e++;
}

vector<int> st[N], ed[N];
int sid[N], tid[N], id[N], dc;

void dfs(int u, int p) {
	sid[u] = dc+1;
	for(int i = 0; i < st[u].size(); ++i) id[st[u][i]] = ++dc;
	for(int i = fst[u]; ~i; i = nxt[i] ){
		int v = vv[i];
		if(v == p) continue;
		dfs(v, u);
	}
	tid[u] = dc;
}

struct node {
	int u, v, c;
	node() {}
	node(int u, int v, int c) : u(u), v(v), c(c) {};
}que[N];


int n, m;
LL mi[N<<2], lazy[N<<2];
LL dp[N];

void build(int ll, int rr, int i) {
	if(ll > rr) return ;
	mi[i] = inf;
	if(ll == rr) return ;
	build(lson);
	build(rson);
}

void up(int i) {
	mi[i] = min(mi[ls], mi[rs]);
	mi[i] = min(mi[i], inf);
}

void down(int i) {
	if(lazy[i]) {
		mi[ls] = min(inf, mi[ls] + lazy[i]);
		mi[rs] = min(inf, mi[rs] + lazy[i]);
		lazy[ls] += lazy[i]; lazy[ls] = min(inf, lazy[ls]);
		lazy[rs] += lazy[i]; lazy[rs] = min(inf, lazy[rs]);
		lazy[i] = 0;
	}
}
LL query(int l, int r, int ll, int rr, int i) {
	if(l > r) return inf;
	if(l == ll && r == rr) {
		return mi[i];
	}
	down(i);
	if(r <= md) return query(l, r, lson);
	else if(l > md) return query(l,r, rson);
	else return  min(query(l, md, lson), query(md+1, r, rson));
}


void update(int x, LL v, int ll, int rr, int i) {
	if(ll == rr) {
		mi[i] = v;
		return ;
	}
	down(i);
	if(x <= md) update(x, v, lson);
	else update(x, v, rson);
	up(i);
}

void update(int l, int r, LL v, int ll, int rr, int i) {
	if(l > r) return ;
	if(l == ll && r == rr) {
		mi[i] = min(inf, mi[i] + v);
		lazy[i] += v;
		lazy[i] = min(inf, lazy[i]);
		return ;
	}
	down(i);
	if(r <= md) update(l, r, v, lson);
	else if(l > md) update(l, r, v, rson);
	else update(l, md, v, lson), update(md+1, r, v, rson);
	up(i);
}
void f(int u, int p) {
	LL tot = 0;
	for(int i = fst[u]; ~i; i = nxt[i]) {
		int v = vv[i];
		if(v == p) continue;
		f(v, u);
		tot += dp[v];
	}
	if(u == 1) {
		dp[u] = tot;
		return ;
	}
	for(int i = 0; i < st[u].size(); ++i) 
		update(id[st[u][i]],tot+ que[st[u][i]].c , 1, m, 1);
	for(int i = 0; i < ed[u].size(); ++i)
		update(id[ed[u][i]], inf, 1, m, 1);
	for(int i = fst[u]; ~i; i = nxt[i]) {
		int v = vv[i];
		if(v == p) continue;
		update(sid[v], tid[v], tot-dp[v], 1, m, 1);
	}
	dp[u] = query(sid[u], tid[u], 1, m, 1);
}

int main() {
	//freopen("in.txt", "r", stdin);
	
	scanf("%d%d", &n, &m);
	int u, v;
	init();
	for(int i = 1; i < n; ++i)
	{
		scanf("%d%d", &u, &v);
		add(u, v), add(v, u);
	}
	for(int i = 1; i <= m; ++i) {
		int w;
		scanf("%d%d%d",&u, &v, &w);
		que[i] = node(u, v, w);
		st[u].push_back(i);
		ed[v].push_back(i);
	}
	dfs(1, 0);
	//build(1, m, 1);
	f(1, 0);
	LL ans = dp[1];
	if(ans >= inf || ans < 0) ans = -1;
	printf("%I64d\n", ans);
}

Codeforces Round #296 (Div. 1) E. Triangles 3000

http://codeforces.com/contest/528/problem/E 先来吐槽一下,一直没机会进div 1, 马力不如当年, 这场题目都不是很难,div 2 四道题都是水题! 题...
  • kevinkitty_love
  • kevinkitty_love
  • 2015年03月19日 17:56
  • 716

Codeforces Round #254 (Div. 1)C. DZY Loves Colors(线段树经典操作/分块)

题目链接 C. DZY Loves Colors time limit per test 2 seconds memory limit per test 256 mega...
  • fouzhe
  • fouzhe
  • 2017年02月11日 15:17
  • 277

解题报告:Codeforces Round #433 (Div. 2) E. Boredom ( 离线处理+树状数组)

题目链接 题意: n*n的矩阵,有n个不同行列的格子染色,染色的格子两两之间组成的矩阵定义为beautiful。 q组询问,每次给出一个矩阵,询问与它相交的beautiful的矩阵的数目 ...
  • qq_32570675
  • qq_32570675
  • 2017年09月07日 09:56
  • 334

Codeforces Round #286 div.1 D 506D D. Mr. Kitayuta's Colorful Graph【并查集】

题目链接:http://codeforces.com/problemset/problem/506/D 题目大意: 给出n个顶点,m条边,每条边上有一个数字,代表某个颜色。不同数字代表不同的颜色。...
  • u013912596
  • u013912596
  • 2015年01月30日 01:40
  • 887

Codeforces Round #445 Div1 D:Symmetric Projections (计算几何)

题目传送门:http://codeforces.com/contest/889/problem/D题目大意:现在有n个点,求有多少条过原点的直线l,使得这n个点在l上的投影构成的可重点集关于某个点P对...
  • KsCla
  • KsCla
  • 2017年12月15日 19:04
  • 109

Codeforces Round #258 (Div. 2)-(A,B,C,D,E)

A:Game With Sticks 水题。。。每次操作,都会拿走一个横行,一个竖行。 所以一共会操作min(横行,竖行)次。 #include #include #include #include ...
  • rowanhaoa
  • rowanhaoa
  • 2014年07月25日 14:39
  • 1470

Codeforces Round #352 (Div. 2) C D

Codeforces Round #352 (Div. 2) C. Recycling Bottles 题目链接:点这里!!!! 题意: A、B两个人的任务负责把地图上的n个...
  • u014325920
  • u014325920
  • 2016年05月12日 20:51
  • 212

Codeforces Round #444 (Div. 2) D. Ratings and Reality Shows 贪心

http://codeforces.com/problemset/problem/887/D 题意:有一个模特,她有一个初始rating值 s。她每天可能进行拍照或show中的一种活动。每拍一次...
  • qq_36553623
  • qq_36553623
  • 2017年11月08日 23:47
  • 187

Codeforces Round #445 Div1 E:Mod Mod Mod (平衡树优化DP)

题目传送门:http://codeforces.com/contest/889/problem/E题目大意:有一个长度为n的序列a。定义函数f(x,n)f(x,n)值为xmodanx \mod a_n...
  • KsCla
  • KsCla
  • 2017年12月17日 20:42
  • 141

Codeforces Round #305 (Div. 1)E. Mike and Friends【后缀数组+线段树】

传送门:Codeforces Round #305 (Div. 1)E. Mike and Friends这题既然求得是子串,就可以用后缀数组来做(也可以用后缀自动机balabala) 我的方法是O...
  • u013007900
  • u013007900
  • 2015年05月31日 20:56
  • 582
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Codeforces Round #352 div1 C D (智商+线段树)
举报原因:
原因补充:

(最多只允许输入30个字)