首页 > 其他 > 详细

Multi-University Training Contest L - Wavel Sequence

时间:2020-07-09 19:44:31      阅读:63      评论:0      收藏:0      [点我收藏+]

在多校前,练练手,发现自己真的好菜。
一开始队友开了签到题,我随便一看看到了M,然后写了一个待修主席树,然后呢大概长这个样子

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<‘0‘ || ch>‘9‘) { if (ch == ‘-‘)f = -1; ch = getchar(); }
	while (ch >= ‘0‘ && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
int T;
int n, m;
struct zxs {
	int ls[N * 300];
	int rs[N * 300];
	int tr[N * 300];
	ll tr2[N * 300];
	int root[N];
	int tot = 0;
	vector<int>vecl, vecr;
	void clear()
	{
		vecl.clear(); vecr.clear();
		tot = 0;
		upd(i, 0, N * 290)ls[i] = rs[i] = tr[i] = 0;
		upd(i, 0, n)root[i] = 0;
	}
	int lowbit(int i)
	{
		return i & (-i);
	}
	void modify(int &o,int l,int r,int k,int val,int pos)
	{
		if (!o)o = ++tot;
		tr[o] += val;
		tr2[o] += 1ll * val * pos;
		if (l == r)return;
		int mid = (l + r) >> 1;
		if (k <= mid)modify(ls[o], l, mid, k, val, pos);
		else modify(rs[o], mid + 1, r, k, val, pos);
	}
	void pre_modify(int x, int k,int val)
	{
		for (int i = x; i <= n; i += lowbit(i))
			modify(root[i], 1, n, k, val,i);
	}
	int query(int l, int r, int k,int L,int R)
	{
		if (l == r)return l;
		int mid = (l + r) >> 1;
		int tsum = 0;
		for (auto p : vecr)
		{
			tsum += 1ll*(R + 1)*tr[ls[p]] - tr2[ls[p]];
		}
		for (auto p : vecl)
		{
			tsum -= 1ll*(L + 1)*tr[ls[p]] - tr2[ls[p]];
		}
		if (tsum >= k)
		{
			for (int i = 0; i < vecr.size(); i++)vecr[i] = ls[vecr[i]];
			for (int i = 0; i < vecl.size(); i++)vecl[i] = ls[vecl[i]];
			return query(l, mid, k, L, R);
		}
		else {
			for (int i = 0; i < vecr.size(); i++)vecr[i] = rs[vecr[i]];
			for (int i = 0; i < vecl.size(); i++)vecl[i] = rs[vecl[i]];
			return query(mid + 1, r, k - tsum, L, R);
		}
	}
	int pre_query(int l, int r, int k)
	{
		vecl.clear(); vecr.clear();
		for (int i = r; i; i -= lowbit(i))vecr.push_back(root[i]);
		for (int i = l - 1; i; i -= lowbit(i))vecl.push_back(root[i]);
		return query(1, n, k, l, r);
	}
	int query_v(int l, int r, int k,int L,int R)
	{
		int tsum = 0;
		if (l == r) {
			for (auto p : vecr)
				tsum += 1ll * (R + 1)*tr[p] - tr2[p];
			for (auto p : vecl)
				tsum -= 1ll * (L + 1)*tr[p] - tr2[p];
			return tsum;
		}
		int mid = (l + r) >> 1;
		if (mid >= k)
		{
			for (int i = 0; i < vecr.size(); i++)vecr[i] = ls[vecr[i]];
			for (int i = 0; i < vecl.size(); i++)vecl[i] = ls[vecl[i]];
			return query_v(l, mid, k, L, R);
		}
		else {
			for (int i = 0; i < vecr.size(); i++)vecr[i] = rs[vecr[i]];
			for (int i = 0; i < vecl.size(); i++)vecl[i] = rs[vecl[i]];
			return query_v(mid + 1, r, k, L, R);
		}
	}
	int pre_val(int l, int r, int k)
	{
		vecl.clear(); vecr.clear();
		for (int i = r; i; i -= lowbit(i))vecr.push_back(root[i]);
		for (int i = l - 1; i; i -= lowbit(i))vecl.push_back(root[i]);
		return query_v(1, n, k, l, r);
	}
}TR;
int main()
{
	T = read();
	while (T--)
	{
		n = read(), m = read();
		TR.clear();
		int u;
		upd(i, 1, n)
		{
			u = read();
			TR.pre_modify(i, u, 1);
		}
		int op, l, r, x, y;
		while (m--)
		{
			op = read();
			if(op==1)
			{
				l = read(), r = read(); x = read(), y = read();
				int vv = TR.pre_val(l, r, x);
				TR.pre_modify(l, x, -vv);
				TR.pre_modify(r + 1, x, vv);
				TR.pre_modify(l, y, vv);
				TR.pre_modify(r + 1, y, -vv);
			}
			else {
				l = read(), r = read(); x = read();
				printf("%d\n", TR.pre_query(l, r, x));
			}
		}
	}
	return 0;
}

后来发现分块才是正解。
我是这样想的,询问第k大不用多说,修改的时候,先查找区间里面,x有多少个,然后区间修改,这里使用树状数组的修改方式,记录\(sum[i],i*sum[i]\)
这样的话查询变成\((pos+1)*sum[i]-sum[i]*i\)即可。然而,发现MLE。空间完全承受不住,然后就GG了,用了一个多小时划水。
然后配队友开了H,两个小时过了H。然后又去接着搞D。
最后一个小时写的L。写的时候一开始想用树状数组去解决,然后T了三发(真要吐了)。然后想了暴力求前缀的方式,去维护


题解:
\(dp[i][j][0]\)表示以第i个结尾,另一个串以j结尾,长度为偶数的答案。
\(dp[i][j][1]\)表示以第i个结尾,另一个串以j结尾,长度为奇数的答案。
当且仅当\(a[i]==b[j]\)的时候,有转移。
可以发现\(dp[i][j][0]\)的转移为他前面,所有\(a[k]<a[i]\)并且\(k<i\)转移而来。
同理,奇数相反。故我们令\(sum[j][0],sum[j][1]\)表示\(b[j]\)的所有偶数\奇数前缀和。当\(a[i]<b[j]\)时,说明这个\(b[j]\)可以作为偶数结尾(\(a[i]==b[j]\))同理可以推奇数结尾。故我们就能在\(o(n*m)\)的时间内,维护出答案。
总结:自己太菜了

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<‘0‘ || ch>‘9‘) { if (ch == ‘-‘)f = -1; ch = getchar(); }
	while (ch >= ‘0‘ && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
int T;
const int N = 2e3 + 10;
const int mod = 998244353;
ll a[N], b[N];
int n, m;
ll dp[N][N][10];
ll sum[N][2];
vector<int>vec;
int id[N];
ll add(ll a, ll b)
{
	return a + b >= mod ? a + b - mod : a + b;
}
int main()
{
	T = read();
	while (T--)
	{
		n = read(), m = read();
		upd(i, 0, n)upd(j, 0, m)upd(k, 0, 1)dp[i][j][k] = sum[i][k] = 0;
		upd(i, 1, n)a[i] = read(), vec.push_back(a[i]);
		upd(i, 1, m)b[i] = read();
		ll ans = 0;
		upd(i, 1, n)
		{
			ll cnt0 = 0, cnt1 = 0;
			upd(j, 1, m)
			{
				if (a[i] == b[j])
				{
					ans = add(cnt1, ans);
					ans = add(cnt0 + 1, ans);
					dp[i][j][0] = add(cnt1, dp[i][j][0]);
					dp[i][j][1] = add(cnt0 + 1, dp[i][j][1]);
				}
				else if (a[i] < b[j])
				{
					cnt0 = add(cnt0, sum[j][0]);
				}
				else {
					cnt1 = add(cnt1, sum[j][1]);
				}
			}
			upd(j, 1, m)
			{
				sum[j][0] = add(sum[j][0], dp[i][j][0]);
				sum[j][1] = add(sum[j][1], dp[i][j][1]);
			}
		}
		cout << ans << endl;
	}
	return 0;
}

Multi-University Training Contest L - Wavel Sequence

原文:https://www.cnblogs.com/LORDXX/p/13275515.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!