2022.3.21 训练

A : Glass Carving

题目链接
题意:给定一个矩形和一些操作 每次横切或者竖切 问你每次切完后的最大矩形
题解:我们每次只需要知道横向和竖向最大的间隔是多少就可以了 先用set维护横切和竖切 然后用multiset维护横竖的最大间隔(利用set里的前驱和后继)

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
set <int> s1,s2;
multiset <int> p1,p2; 
int main()
{
	int w,h,n;
	cin>>w>>h>>n;
	s1.insert(0),s1.insert(w);
	s2.insert(0),s2.insert(h);
	p1.insert(w),p2.insert(h);
	while(n--)
	{
		char s[20];
		int v;
		scanf("%s",s);
		if(s[0]=='V')
		{
			cin>>v;
			if(s1.find(v)!=s1.end()) continue;
			auto it=s1.lower_bound(v);
			int x1=*it;
			it--;
			int x2=*it;
			p1.insert(x1-v),p1.insert(v-x2);
			p1.erase(p1.find(x1-x2));
			s1.insert(v);
		}
		else
		{
			cin>>v;
			if(s2.find(v)!=s2.end()) continue;
			auto it=s2.lower_bound(v);
			int x1=*it;
			it--;
			int x2=*it;
			//cout<<x1<<" "<<x2<<endl;
			p2.insert(x1-v),p2.insert(v-x2);
			p2.erase(p2.find(x1-x2));
			s2.insert(v);
		}
		auto it1=p1.end(),it2=p2.end();
		it1--,it2--;
		cout<<1ll*(*it1)*(*it2)<<endl;
	}
	return 0;
}

B:Ryouko’s Memory Note

题意:
在这里插入图片描述
题解:
对于某个值 我们可以维护某个值的所有相邻不同的值 那么肯定是改到这些值中间的值是最优的
然后对于所有的n个值维护最大更改插值就可以了。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#define int long long
using namespace std;
const int maxm=1e5+100;
vector <int> s[maxm];
int a[maxm];
signed main()
{
	int n,m;
	int sum=0,ans=0;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>a[i];
		if(a[i]!=a[i-1]&&i!=1)
			s[a[i]].push_back(a[i-1]),s[a[i-1]].push_back(a[i]),sum+=abs(a[i]-a[i-1]);
	}
	for(int i=1;i<=n;i++)
	if(!s[i].empty())
	{
		sort(s[i].begin(),s[i].end());
		int pos=s[i].size()/2;
		int x=s[i][pos];
		int tot1=0,tot2=0;
		for(int j=0;j<s[i].size();j++)
		{
			tot1+=abs(s[i][j]-x);
			tot2+=abs(s[i][j]-i);
		}
		ans=max(ans,tot2-tot1);
	}
	cout<<1ll*(sum-ans)<<endl;
	return 0;
}

C : Multipliers

题意:给定一个数字的质因数分解形式 求所有因子的乘积对1e9+7取模
n = p 1 k 1 ∗ p 2 k 2 ∗ . . . ∗ p m k m n=p_{1}^{k_{1}}*p_{2}^{k_{2}}*...*p_{m}^{k_{m}} n=p1k1p2k2...pmkm
令 M = ( k 1 + 1 ) ∗ ( k 2 + 1 ) ∗ . . ∗ ( k m + 1 ) 令M=(k_1+1)*(k_2+1)*..*(k_m+1) M=(k1+1)(k2+1)..(km+1)
可 以 得 出 A n s = Π P i M ∗ k i 2 可以得出Ans=\Pi{P_{i}^{\frac{M*k_i}{2}}} Ans=ΠPi2Mki
对于上面的 幂次要用欧拉降幂 为了防止2被模没了 先对模数乘2 2求逆元。
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<unordered_map>
#define ll long long
#define inf 0x3f3f3f3f
#define Inf 0x3f3f3f3f3f3f3f3f
#define int  ll
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
using namespace std;
int read()
{
	int res = 0,flag = 1;
	char ch = getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch == '-') flag = -1;
		ch = getchar();
	}
	while(ch>='0' && ch<='9')
	{
		res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
		ch = getchar();
	}
	return res*flag;
}
const int maxn = 1e6+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
int n,mul,res;
map<int,int>mp;
int qpow(int a,int b)
{
	int res = 1;
	while(b)
	{
		if(b&1) res = 1LL*a*res%mod;
		a = 1LL*a*a%mod;
		b >>= 1;
	}
	return res;
}
signed main()
{
	n = read();
	for(int i = 1;i <= n;i++)
	{
		int x = read();
		mp[x]++;
	}
	int sum = 1,res = 1;
	for(auto it:mp) sum = sum*(it.second+1)%(2*(mod-1));
	// cout<<sum<<endl;
	for(auto it:mp)
	{
		int val = it.first,cnt = it.second;
		res = res*qpow(val,sum*cnt/2%(mod-1)+mod-1)%mod;
	}
	cout<<res<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值