Codeforces Round #759 (Div. 2, based on Technocup 2022 Elimination Round 3)

感觉E思路明确只用了stl+树状数组,F线段树复合修改,为什么都是2400。
A. Life of a Flower
B. Array Eversion
C. Minimize Distance
E. Frequency Queries
F. Non-equal Neighbours



F : 首先 d p [ i ] [ j ] = s u m [ d p [ i − 1 ] ] − d p [ i − 1 ] [ j ] dp[i][j] = sum[dp[i-1]] - dp[i-1][j] dp[i][j]=sum[dp[i1]]dp[i1][j],但这样是 ∑ i = 1 n a [ i ] \sum_{i=1}^na[i] i=1na[i],  然后线段树优化。

具体和Transformation HDU - 4578一样

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <set>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 2e5 + 10, mod = 998244353;

int val[N<<5], ls[N<<5] ,rs[N<<5], idx = 0, lazy1[N<<5];
bool lazy2[N<<5];
int root;

void add_tage(int &u, int l, int r, LL x, bool f)  // Transformation HDU - 4578 的简化版; 
{
	if(!u) u = ++idx;    
	if(f) val[u] = 0, lazy1[u] = 0, lazy2[u] = f;
	if(x) val[u] = (val[u] + x*(r-l+1))%mod, lazy1[u] = (lazy1[u] + x)%mod;	
}
void push_down(int u, int l, int r)
{
	if(!lazy1[u]&&!lazy2[u]) return ;
	add_tage(ls[u], l, mid, lazy1[u], lazy2[u]);
	add_tage(rs[u], mid+1, r, lazy1[u], lazy2[u]);
	lazy1[u] = lazy2[u] = 0;
}
void push_up(int u){val[u] = (val[ls[u]]+val[rs[u]])%mod;}

void modify(int &u, int l, int r, int L, int R, int x, bool f)
{
	if(!u)u = ++idx;
	if(L <= l&& R >= r)
		add_tage(u, l, r, x, f);
	else{
		push_down(u, l, r);
		if(L <= mid) modify(ls[u], l, mid, L, R, x, f);
		if(R > mid) modify(rs[u], mid+1, r, L, R, x, f);
		push_up(u);
	}
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1;i <= 1;i ++) // 额,为了看着好看; 
    {
    	int x;
    	scanf("%d", &x);
    	modify(root, 1, 1e9+1, 1, x, -1, 0); // r = 1e9+1 的原因是 下面的x+1,好像x=1e9有问题吧。  
	}
	for(int i = 2;i <= n;i ++)
    {
    	int x;
    	scanf("%d", &x);
    	LL sum = -val[root];
    	modify(root, 1, 1e9+1, 1, x, sum, 0);
    	modify(root, 1, 1e9+1, x+1, 1e9+1, 0, 1);
	}
	val[root] = (val[root]+mod)%mod;         
	if(n&1) val[root] = (mod-val[root])%mod; 
	// 这里面正负不会搞,照着test7和test3 d的; 
	// 具体是n是奇数的话总和等于-ans,偶数等于ans,但是另一种正负要这么写取模; 
	cout<<val[root]<<endl;
    return 0;
}

E : 简单stl应用 + 离线

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <set>
#define mid (l+r>>1)
#define lowbit(x) (x&-x)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 1e6 + 10, mod = 998244353;

int tr[N], a[N], n, q, ans[N], time[N];
set<int> se[N];
vector<pair<int,PII> > Q[N];
vector<int> G[N];

void add(int u, int f){while(u <= n)tr[u]+=f,u+=lowbit(u);}
int quary(int u){int ans = 0;while(u)ans+=tr[u],u-=lowbit(u);return ans;}
void dfs(int u)
{
	if(time[a[u]])
		se[time[a[u]]].erase(a[u]), add(time[a[u]], -1);
	time[a[u]] ++;
	se[time[a[u]]].insert(a[u]); add(time[a[u]], 1);
	for(auto x:Q[u])
	{
		int id = x.first, m = x.second.first, t = x.second.second;
		int sum = quary(m-1)+t, l = 1, r = n;
		if(quary(n) < sum)
		{
			ans[id] = -1; 
			continue;
		}
		while(l < r)
			if(quary(mid)>=sum)r = mid;
			else l = mid+1;
		
		ans[id] = *se[l].begin();
	}
	for(auto x:G[u])
		dfs(x);
		
	se[time[a[u]]].erase(a[u]); add(time[a[u]], -1);
	time[a[u]] --;
	if(time[a[u]])
		se[time[a[u]]].insert(a[u]), add(time[a[u]], 1);
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
    	scanf("%d%d", &n, &q);
    	for(int i = 1;i <= n;i ++)
    		scanf("%d", a+i), 
			G[i].clear(), tr[i] = time[i] = 0, 
			se[i].clear(), 	Q[i].clear();
    	for(int i = 2;i <= n;i ++)
    	{
    		int p;
    		scanf("%d", &p);
    		G[p].push_back(i);
		}
		for(int i = 1;i <= q;i ++)
		{
			int v, l, k;
			scanf("%d%d%d", &v, &l, &k);
			Q[v].push_back({i, {l, k}});
		}
		dfs(1);
		for(int i = 1;i <= q;i ++)
			printf("%d ", ans[i]);
		puts("");
    }
    return 0;
}

B : 我傻逼了,哎最近比它大的数的位置直接遍历就行,我还排个序。。
   S B 代 码 SB代码 SB

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
#define mid (l + r >> 1)
#define lowbit(x) (x & -x)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 3e5 + 10, mod = 998244353;

PII a[N];
int ma[N];

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
    	int n;
    	scanf("%d", &n);
    	for(int i = 1;i <= n;i ++)
    	{
    		scanf("%d", &a[i].first);
    		a[i].second = i;
		}
		a[n+1] = {0, 0};
		sort(a+1, a+n+1);
		int h = n;
		for(int i = n;i >= 1;i --)
		{
			if(a[i].first == a[i+1].first) ma[i] = ma[i+1];
			else ma[i] = h;
			if(a[i].second > a[h].second) h = i;
			if(a[i].second == n)
			{
				int ans = 0;
				while(i < n)
				{
					ans ++;
					i = ma[i];
				}
				cout<<ans<<endl;
				break;
			}
		} 
    }
    return 0;
}

   超 简 单 代 码 超简单代码

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
#define mid (l + r >> 1)
#define lowbit(x) (x & -x)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 3e5 + 10, mod = 998244353;

int a[N];

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
    	int n;
    	scanf("%d", &n);
    	for(int i = 1;i <= n;i ++)
    		scanf("%d", a+i);
    	int ans = 0, ma = a[n];
    	for(int i = n-1;i >= 1;i --)
    		if(a[i] > ma)
			{
				ma = a[i];
				ans ++;
			}
		cout<<ans<<endl;
    }
    return 0;
}

C : 直接算 + 边界

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
#define mid (l + r >> 1)
#define lowbit(x) (x & -x)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 3e5 + 10, mod = 998244353;

int a[N];

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
    	int n, k;
    	LL ans = 0;
    	scanf("%d%d", &n, &k);
    	for(int i = 1;i <= n;i ++)
    		scanf("%d", a+i);
    	sort(a+1, a+n+1);
    	for(int i = 1;i <= n;ans -= a[i], i += k)
    		if(a[i] > 0)break;
		
		for(int i = n;i >= 1;ans += a[i], i -= k)
			if(a[i] < 0)break;
		ans = ans*2 - max(-a[1], a[n]);
		cout<<ans<<endl;
    }
    return 0;
}

A : 模拟

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
#define mid (l + r >> 1)
#define lowbit(x) (x & -x)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 3e5 + 10, mod = 998244353;

int main()
{
    int t;
    scanf("%d", &t);
    while(t --)
    {
      int n, ans = 1, now = 0;
      scanf("%d", &n);
      for(int i = 1;i <= n;i ++)
      {
        int x;
        scanf("%d", &x);
        if(ans == -1)continue;
        if(x) ans += now == i-1&&now?5:1, now = i;
        else if(now == i-2)ans = -1;
      }
      cout<<ans<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昌荣。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值