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=p1k1∗p2k2∗...∗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=ΠPi2M∗ki
对于上面的 幂次要用欧拉降幂 为了防止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;
}