首页 > 其他分享 >CodeForces 1609F Interesting Sections

CodeForces 1609F Interesting Sections

时间:2024-01-22 12:24:30浏览次数:37  
标签:vc Interesting CodeForces top1 top2 stk1 stk2 Sections define

洛谷传送门

CF 传送门

看到 \(\max, \min\) 考虑单调栈。枚举右端点,计算有多少个符合条件的左端点。

单调栈维护的是对于每个右端点,以每个点为左端点的后缀 \(\max, \min\) 形成的极长的段。先枚举 \(\text{popcount} = k\),然后如果一个段的 \(\max\) 的 \(\text{popcount} = k\) 就在线段树上把这段区间 \(+1\)。\(\min\) 同理。那么查询就是查 \([1, n]\) 的 \(2\) 的个数。可以维护区间最大值个数解决。

时间复杂度 \(O(n (\log n + \log V))\)。但是因为 \(\log n\) 是线段树的 \(\log\) 所以要卡常才能通过。

code
// Problem: F. Interesting Sections
// Contest: Codeforces - Deltix Round, Autumn 2021 (open for everyone, rated, Div. 1 + Div. 2)
// URL: https://codeforces.com/problemset/problem/1609/F
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline ll read() {
    char c = getchar();
    ll x = 0;
    for (; !isdigit(c); c = getchar()) ;
    for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x;
}

const int maxn = 1000100;

ll n, a[maxn];

struct node {
	int mx, cnt, tag;
};

inline node operator + (const node &a, const node &b) {
	node res;
	res.mx = max(a.mx, b.mx);
	res.cnt = (a.mx == res.mx ? a.cnt : 0) + (b.mx == res.mx ? b.cnt : 0);
	res.tag = 0;
	return res;
}

namespace SGT {
	node a[maxn << 2];
	
	inline void pushup(int x) {
		a[x] = a[x << 1] + a[x << 1 | 1];
	}
	
	inline void pushdown(int x) {
		if (!a[x].tag) {
			return;
		}
		int &t = a[x].tag;
		a[x << 1].mx += t;
		a[x << 1].tag += t;
		a[x << 1 | 1].mx += t;
		a[x << 1 | 1].tag += t;
		t = 0;
	}
	
	void build(int rt, int l, int r) {
		a[rt].mx = a[rt].tag = 0;
		a[rt].cnt = r - l + 1;
		if (l == r) {
			return;
		}
		int mid = (l + r) >> 1;
		build(rt << 1, l, mid);
		build(rt << 1 | 1, mid + 1, r);
	}
	
	void update(int rt, int l, int r, int ql, int qr, int x) {
		if (ql <= l && r <= qr) {
			a[rt].mx += x;
			a[rt].tag += x;
			return;
		}
		pushdown(rt);
		int mid = (l + r) >> 1;
		if (ql <= mid) {
			update(rt << 1, l, mid, ql, qr, x);
		}
		if (qr > mid) {
			update(rt << 1 | 1, mid + 1, r, ql, qr, x);
		}
		pushup(rt);
	}
}

int stk1[maxn], top1, stk2[maxn], top2, hd[maxn], len, nxt[maxn << 2];

struct wwh {
	int l, r, x;
	wwh(int a = 0, int b = 0, int c = 0) : l(a), r(b), x(c) {}
} to[maxn << 2];

inline void add(int x, wwh y) {
	to[++len] = y;
	nxt[len] = hd[x];
	hd[x] = len;
}

void solve() {
	n = read();
	for (int i = 1; i <= n; ++i) {
		a[i] = read();
	}
	for (int i = 1; i <= n; ++i) {
		vector<wwh> vc;
		while (top1 && a[stk1[top1]] < a[i]) {
			vc.pb(stk1[top1 - 1] + 1, stk1[top1], -__builtin_popcountll(a[stk1[top1]]) - 1);
			--top1;
		}
		vc.pb(stk1[top1] + 1, i, __builtin_popcountll(a[i]) + 1);
		stk1[++top1] = i;
		while (top2 && a[stk2[top2]] > a[i]) {
			vc.pb(stk2[top2 - 1] + 1, stk2[top2], -__builtin_popcountll(a[stk2[top2]]) - 1);
			--top2;
		}
		vc.pb(stk2[top2] + 1, i, __builtin_popcountll(a[i]) + 1);
		stk2[++top2] = i;
		sort(vc.begin(), vc.end(), [&](const wwh &a, const wwh &b) {
			return abs(a.x) > abs(b.x);
		});
		for (wwh u : vc) {
			add(i, u);
		}
	}
	ll ans = 0;
	for (int j = 0; j < 60; ++j) {
		SGT::build(1, 1, n);
		for (int i = 1; i <= n; ++i) {
			while (hd[i] && abs(to[hd[i]].x) == j + 1) {
				wwh u = to[hd[i]];
				hd[i] = nxt[hd[i]];
				SGT::update(1, 1, n, u.l, u.r, u.x > 0 ? 1 : -1);
			}
			if (SGT::a[1].mx == 2) {
				ans += SGT::a[1].cnt;
			}
		}
	}
	printf("%lld\n", ans);
}

int main() {
	// freopen("1.in", "r", stdin);
	// freopen("my.out", "w", stdout);
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:vc,Interesting,CodeForces,top1,top2,stk1,stk2,Sections,define
From: https://www.cnblogs.com/zltzlt-blog/p/17979785

相关文章

  • (区间覆盖问题)P5019 [NOIP2018 提高组] 铺设道路和Educational Codeforces Round 158 (
    区间覆盖问题这里EducationalCodeforcesRound158(RatedforDiv.2)b题和[NOIP2018提高组]铺设道路两道典型题目,本质是相同的。这里由于题目多次出现,特此记录。解题思路:首先我们得对区间做划分,那么划分思路可以是从小到大也可以是从大到小的异常点来做划分(我这是由大到......
  • hey_left 12 Codeforces Round 859 (Div. 4) 续
    F.模拟题,不难只是比较繁琐,需要分情况讨论debug:如何判断永远走不到终点格?原思路是这个点同时这个点指向的方向被经过了,那么就是走的重复的路,走不到终点但不知为何map出了一些问题后来看题解,只要步数很大了还走不到那么就永远走不到于是我把map删了,过了#include<bits/stdc......
  • hey_left 11 Codeforces Round 859 (Div. 4)
    题目链接A.直接判断输出#include<bits/stdc++.h>usingnamespacestd;voidsolve(){inta,b,c;cin>>a>>b>>c;if(a+b==c)cout<<'+'<<'\n';elseif(a-b==c)cout<<"-"<<'\n&#......
  • CodeForces 342E Xenia and Tree
    洛谷传送门CF传送门比较谔谔,为什么题解区都在群魔乱舞。不是有个很简单的点分树做法吗。考虑建出点分树,由点分树的性质可得任意两点在点分树上的LCA一定在它们的路径上。然后每次暴力跳父亲,每个分治中心维护一个\(f_i\)表示距离\(i\)最近的红色点的距离即可。若使用df......
  • 比赛必备——codeforces better 和 atcoder better 的安装教程
    大家有没有像我一样英语不太好然后又想要打cf和atc的呢?(可能全世界就我英语不好)这里有两个强力的工具可以帮助我们解决这一问题——codeforcesbetter和atcoderbetter。由于我只用的是edge,所以下面默认为edge浏览器篡改猴首先我们需要安装篡改猴,link。codeforcesbe......
  • hey_left 10 Codeforces Round 871 (Div. 4) 再续
    题目链接H.没思路,查看题解选择数组的非连续的子序列,就是每个数选或不选的问题求个数,易dp求子序列的数二进制相与结果有k个1的个数把所有结果记录,再去筛选满足条件的结果f[i][j]表示到第i个数,相与结果为j的子序列个数正向思维:多个数相与得到结果dp思维:枚举结果,考虑数如何......
  • hey_left 9 Codeforces Round 871 (Div. 4) 续
    题目链接E.连通块的搜索debug:用不上回溯,把连通块的贡献全部加起来#include<bits/stdc++.h>usingnamespacestd;intn,m;intg[1010][1010];boolvis[1010][1010];intma,tmp;intdx[5]={-1,1,0,0};intdy[5]={0,0,1,-1};voiddfs(intx,inty){tmp+=g[x][y];......
  • Educational Codeforces Round 161 (Rated for Div. 2)
    基本情况A犯病卡半小时。主要就是太着急,题目没有彻底分析清楚就开始想一些错误做法。C最优想法出来的慢。E比较好想。C.ClosestCitiesProblem-C-Codeforces就,显然是能走最近城市就走,不行就不走。一开始弄了一个自作聪明的预处理,但实际上每次查询还是\(\operatorn......
  • Codeforces Round 920 (Div. 3)
    题目链接点这里这场div3F题的算法很基础,但是我此前居然完全没接触过。(芙莉莲震惊.jpg)不过这下能够算法沙漠面积--了。CF1921ASquarevoidsolve(){intx1=1e9,y1=1e9,x2=-1e9,y2=-1e9,x,y;for(inti=1;i<=4;++i){cin>>x......
  • Educational Codeforces Round 161 (Rated for Div. 2)
    A.TrickyTemplate思维有点难转过来,而且当时在C也能匹配c这卡了很久#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ intn; cin>>n; stringa,b,c; cin>>a>>b>>c; intcnt=0; intf=0; for(inti=0;i<n;i++){ if(a[i]!=c[i]&&a......