目录
A.Perfectly Imperfect Array
题意:给你个序列判断子序列之积不是理想的平方数
所以在给你的一串数组里判断是否有一个不是平方数即可
#include<bits/stdc++.h>
#define ll unsigned long long
#define N 100005
using namespace std;
ll t, n, m, x, xx, sum;
int main() {
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>t;
while(t--) {
cin>>n;
q=0;
for(int i=1; i<=n; i++) {
cin>>x;
xx=sqrt(x);
if(xx*xx==x) q++;//不能直接sqrt*sqrt好像会WA
}
if(q==n) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
/*
2
3
1 5 4
2
100 10000
*/
B.AND 0, Sum Big
题意:给你n和k,创造一个长为n的数组,数组元素为[0,2^k-1],并且元素按位与全是0的不同数组个数
这题各种想组合数然后就掉分了
其实最大值是固定的,然后就是分配k-1个位置
#include<bits/stdc++.h>
#define ll unsigned long long
#define N 100005
using namespace std;
const ll M=1e9+7;
ll n, m, k, t, sum;
ll ksm(ll a,ll p){ll res=1;while(p){if(p&1){res=res*a%M;}a=a*a%M;p>>=1;}return res;}
int main() {
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>t;
while(t--) {
cin>>n>>k;
cout<<ksm(n, k)<<endl;
}
return 0;
}
/*
2
2 2
100000 20
*/
C.Product 1 Modulo N
题意:给你n,求长度范围为[1, n-1]的数组 所有数组元素相乘%n==1
其实也是猜的 假如有公因子的话 到最后乘积%n就==0了比如 6!%9=0 7!%9=0 7!%9=0 8!%9=0
所以就是不能放和n有公因子的数,不然乘积不与n互素,就不可能等于1;最后要特判一下n-1。
威尔逊定理 当且仅当n是素数 (n-1)!mod n=n-1
也可以dfs打表找规律少了哪些数
//AC代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e6 + 9;
ll n, m, t, q, a[N], cnt;
int main() {
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n;
m=1;
for(ll i=1; i<=n-1; i++) {
if(i==n-1) if(m*i%n!=1) continue;
if(__gcd(n, i)==1) {
m*=i;
m%=n;//忘记取余了掉大分
a[++q]=i;
}
}
cout<<q<<endl ;
for(int i=1; i<=q; i++) {
cout<<a[i]<<" \n"[i==q];
}
return 0;
}
//打表代码
ll n, m, t, q, a[N], cnt;
vector<int> v, res;
void dfs(ll s, ll now, ll en) {
if(s==en) {
if(now==1&& res.size()<v.size())//比原来的长并且取模为1就更新(题目要最长
res=v;
return;
}
dfs(s+1, now, en);//不取这个数
for(int i=s ; i<en; i++) {
v.push_back(i);
dfs(i+1, now*i%en, en);//取这个数
v.pop_back();
}
}
int main(){
cin>>n;
for(int i=2 ; i<=n ; i++) {
v.clear();
res.clear();
dfs(1, 1, i);
cout <<i<<" : "<<res.size()<<endl;
sort(res.begin(), res.end());
for(auto x: res)
cout<<x<< " ";
cout<<endl;
}
return 0;
}
D.Cut and Stick
比赛的时候也没看,看了也没想到最优的切法
题意:给你个
a
a
a数组和
q
q
q次询问。每次询问给你
l
l
l 和
r
r
r;问把区间
[
l
,
r
]
[ l , r]
[l,r] 最少分为几段,使区间内出现最多次的数
s
s
s的次数
<
=
(
m
+
1
)
/
2
<=(m+1)/2
<=(m+1)/2,
m
=
r
−
l
+
1
m=r-l+1
m=r−l+1即区间长度。
最优的切分方法是将剩下的 m − f m − f m−f元素搭配上 m − f + 1 m − f + 1 m−f+1 个 s s s,其余的 s s s切分成单个数的序列。共需要 1 + f − ( m − f + 1 ) = 2 f − m 1 + f − ( m − f + 1 ) = 2 f − m 1+f−(m−f+1)=2f−m次。
莫队
随机化算法(官方
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
int a[N], n, q, l, r;
vector<int> G[N];
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int cnt(int k, int l, int r){
return upper_bound(G[k].begin(), G[k].end(), r) - lower_bound(G[k].begin(), G[k].end(), l);
}//二分得数量
int solve(int l, int r){
int ans = 1;
for(int i=1; i<=30; i++){//好像说是2的-30次方的概率不被取到
int pos=uniform_int_distribution<int>(l,r)(rng);//随机数 假定a[pos]是出现次数最大的那个数字
ans=max(ans, 2*cnt(a[pos], l, r)-(r-l+1));//取最大值就是说明这次随机取得cnt比上次大因为长度r-l+1是固定的
}
return ans;
}
int main() {
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>q;
for(int i=1; i<=n; i++){
cin>>a[i];
G[a[i]].push_back(i);//存位置
}
while(q--){
cin>>l>>r;
cout<<solve(l, r)<<endl;
}
return 0;
}
线段树维护出现最大的次数
复杂度 ( n l o g n ) (nlogn) (nlogn)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
int a[N], n, q, l, r, tree[4*N];
vector<int> G[N];
int cnt(int k, int l, int r) {
return upper_bound(G[k].begin(), G[k].end(), r) - lower_bound(G[k].begin(), G[k].end(), l);
}
void build(int p, int l, int r) {//建树
if(l==r) {
tree[p]=a[l];
return;
}
int mid=(l+r)>>1;
build(2*p, l, mid);
build(2*p+1, mid+1, r);
tree[p]=(cnt(tree[2*p], l, r)>cnt(tree[2*p+1], l, r)? tree[2*p]:tree[2*p+1]);
}
int query(int p, int l, int r, int x, int y) {//查询
if(y<x|| r<x|| l>y) return 0;//看清楚
if(l>=x&&r<=y) return cnt(tree[p], x, y);//看清楚
int mid=(l+r)>>1;
return max(query(2*p, l, mid, x, y), query(2*p+1, mid+1, r, x, y));
}
int solve(int l, int r) {
int f=query(1, 1, n, l, r);
return max(1, 2*f-(r-l+1));
}
int main() {
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>q;
for(int i=1; i<=n; i++) {
cin>>a[i];
G[a[i]].push_back(i);//存位置
}
build(1, 1, n);
while(q--) {
cin>>l>>r;
cout<<solve(l, r)<<endl;
}
return 0;
}
/*6 2
1 3 2 3 3 2
1 6
2 5
*/
E.Baby Ehab’s Hyper Apartment
没看 不会 骗访客的
好像有题解了
官方题解