2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题相关的知识,希望对你有一定的参考价值。

Solved Pro.ID Title Ratio(Accepted / Submitted)
1001 I love cube 26.49%(880/3322)(递推)
1002 I love tree 22.47%(60/267)(树链剖分)<n条链每次加x^2>
1003 I love playing games 7.96%(9/113)
*1004 I love counting 22.74%(78/343)(01字典树)<(区间l,r内xor a)<=b的数个数>
1005 I love string 47.41%(952/2008)(找规律,快速幂)
1006 I love sequences 57.89%(11/19)
1007 I love data structure 19.81%(21/106)(线段树超时)
1008 I love exam 24.35%(198/813)(背包)
1009 I love triples 26.79%(15/56)(逆序对0101找规律)
1010 I love permutation 20.82%(61/293)
*1011 I love max and multiply 10.52%(215/2044) (贪心,位运算)
1012 I love 114514 77.98%(1091/1399)(签到,STL)

1001 I love cube

题意:

  • 给出一个边长为n-1的立方体,找出在立方体点上有三个点的等边三角形的数量,点必须是整数。

思路:

  • 考虑大小为1的立方体的时候有8个,然后递推
  • 可以发现规律,对于边长为i的正方形,答案为8*(n-i)^3,取sum[1~n-1]后答案为2[n(n-1)]^2 (或者k = 8[n(n-1)/2]^2)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e7+10;
const int mod = 1e9+7;

LL mpow(LL a, LL x) {
	if(x==0)return 1;
	LL t = mpow(a, x>>1);
	if(x%2==0)return t*t%mod;
	return t*t%mod*a%mod;
}

int main(){
	int T;  cin>>T;
	while(T--){
		LL n;  cin>>n;  n%=mod;
		// k = 8[n(n-1)/2]^2 = 2[n(n-1)]^2
		LL k = n*(n-1)%mod*mpow(2,mod-2)%mod;//费马小定理求逆元
		k = (k+mod)%mod;
		k = k*k%mod;
		k = 8*k%mod;
		cout<<k<<"\\n";
	}
	return 0;
}

1005 I love string

题意:

  • 给出一个操作字符串,每次按顺序取出字符放入新串的前面或后面,求新串字典序最小时有多少种构造方案。

思路:

  • 因为后面只能放前面和后面,所以是固定的,所以可以发现,答案为2^(k-1),k为操作字符串第一个字母连续重复的个数。需要用到快速幂。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3e6+10;
const LL mod = 1000000007;

LL mul(LL a, LL b, LL p){
    LL x = 0;
    while(b){
        if(b&1)x=(x+a)%p;
        a = (a<<1)%p;
        b >>= 1;
    }
    return x;
}
LL pow(LL a, LL b, LL p){
    LL x = 1;
    while(b){
        if(b&1)x = mul(x,a,p)%p;
        a = mul(a,a,p)%p;
        b >>= 1;
    }
    return x%p;
}

int main(){
    ios::sync_with_stdio(false);
    int T;  cin>>T;
    while(T--){
        int n;  cin>>n;
        string s;  cin>>s;
        LL cc = 0;
        for(int i = 0; i < n; i++){
            if(s[i]==s[0])cc++;
            else break;
        }
        cout<<pow(2,cc-1, mod)<<"\\n";
    }
    return 0;
}

1012 I love 114514

题意:

  • 给出一个字符串,判断是否包含114514

思路:

  • 直接string find一下
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3e6+10;

int main(){
    ios::sync_with_stdio(false);
    int T;  cin>>T;
    while(T--){
        string s;  cin>>s;
        if(s.find("114514")!=string::npos){
            cout<<"AAAAAA\\n";
        }else{
            cout<<"Abuchulaile\\n";
        }
    }
    return 0;
}

1011 I love max and multiply

题意:

  • 给出两个长为n的数组A, B,求Ck=max(Ai*Bj)并满足i&j>=k的C数组,输出C数组的和。

思路:

  • 考虑求出所有的Dk=max{AiBj}并满足i&j=k,然后再从后往前取max。
  • 对于i&j==k,改原式为求Dk=max{AiBj}并满足k属于i&j的,即对于A,B分别求满足k属于i,j时max(ai), min(ai), max(bi), min(bi), 然后分别相乘取最大

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
const int inf=1e9+10;
const int mod=998244353;

int a[maxn],b[maxn], A[maxn],B[maxn];

int main(){
	ios::sync_with_stdio(false);
	int T;  cin>>T;
	while(T--){
		LL n; cin>>n;
		for(int i = 0; i < n; i++){
			cin>>a[i];  A[i]=a[i];
		}
		for(int i = 0; i < n; i++){
			cin>>b[i];  B[i]=b[i];
		}
		int m=1;
		while(m<n)m<<=1;
		for(int i = n; i < m; i++){
			A[i]=B[i]=-inf;
			a[i]=b[i]=inf;
		}
		for(int i = 1; i < m; i<<=1){
			for(int k = 0; k < n; k++){
				if(!(i&k)){
					A[k]=max(A[k], A[i^k]);
					a[k]=min(a[k], a[i^k]);
					B[k]=max(B[k], B[i^k]);
					b[k]=min(b[k], b[i^k]);
				}
			}
		}
		LL t = -(LL)inf*inf, ans = 0;
		for(int i = n-1; i >= 0; i--){
			t = max(t, 1ll*A[i]*B[i]);
			t = max(t, 1ll*A[i]*b[i]);
			t = max(t, 1ll*a[i]*B[i]);
			t = max(t, 1ll*a[i]*b[i]);
			ans = (ans+t%mod)%mod;
		}
		ans = (ans+mod)%mod;
		cout<<ans<<"\\n";
	}
	return 0;
}

1004 I love counting

题意:

  • 给出一个长为n的序列,每次询问区间[l, r]内有多少数满足xi xor a <= b

思路:

  • 维护01字典树,每个节点记录一下子树内的所有点。
  • 对于一个询问,它所包含的是树上的最多logn个子树,对每颗子树做一遍二维数点即可
//暂时不太懂 list, BIT, 01Tire, vector, struct 
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;

int head[maxn], nxt[maxn], c[maxn], ans[maxn];
struct qq{int l, r, a, b; }q[maxn];
struct node{int l, r, x,id;};
bool operator < (const node &a, const node &b){
	if(a.x!=b.x)return a.x<b.x;
	if(a.id!=b.id)return a.id<b.id;
	return a.l<b.l;
}
vector<node>vec[maxn*20];

int n, tot, tr[maxn], ch[maxn*20][2], sum[maxn*20];
void add(int x, int y){while(x<=n)tr[x]+=y, x+=x&-x;}
int query(int x){int ans=0; while(x)ans+=tr[x],x-=x&-x;return ans;}
void query(int rt, int now, int a, int b, int id){
	if(!rt && now!=16)return ;
	if(now < 0){
		vec[rt].push_back(node{q[id].l,q[id].r,n-q[id].r+1, id});
		return ;
	}
	int xx=(a&(1<<now))!=0, yy = (b&(1<<now))!=0;
	if(yy)vec[ch[rt][xx]].push_back(node{q[id].l, q[id].r, n-q[id].r+1, id});
	xx ^= yy;
	query(ch[rt][xx],now-1, a, b, id);
}
void insert(int x, int id){
	int now = 0;
	for(int i=16; i>=0; i--){
		int xx = (x&(1<<i))!=0;
		if(!ch[now][xx])ch[now][xx] = ++tot;
		now = ch[now][xx];
		sum[now]++;
		vec[now].push_back(node{id,0,n-nxt[id]+2,0});
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i = 1; i <= n; i++)cin>>c[i];
	for(int i = n; i >= 1; i--){
		if(!head[c[i]])nxt[i]=n+1;
		else nxt[i]=head[c[i]];
		head[c[i]]=i;
	}
	for(int i = 1; i <= n; i++)insert(c[i],i);
	int Q;  cin>>Q;
	for(int i = 1; i <= Q; i++){
		cin>>q[i].l>>q[i].r>>q[i].a>>q[i].b;
		query(0,16,q[i].a, q[i].b, i);
	}
	for(int i = 1; i <= tot; i++){
		sort(vec[i].begin(), vec[i].end());
		for(auto it : vec[i]){
			if(it.id == 0){
				add(it.l, 1);
			}else{
				ans[it.id] += query(it.r)-query(it.l-1);
			}
		}
		for(auto it : vec[i]){
			if(it.id == 0){
				add(it.l, -1);
			}
		}
	}
	for(int i = 1; i <= Q; i++)
		cout<<ans[i]<<"\\n";
	return 0;
}

以上是关于2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题的主要内容,如果未能解决你的问题,请参考以下文章

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题4题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题2题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题5题

2021杭电多校赛2021“MINIEYE杯”中国大学生算法设计超级联赛签到题4题