比赛链接:https://ac.nowcoder.com/acm/contest/1085#question
除了那道积分数学其他还好
后面没有 F F F题的题解
长度为 n n n的序列, m m m个区间,求最大的没有被任何区间覆盖的区间。
我们将区间按照右端点从大到小枚举,我们每次求从这个右端点往右可以扩展多少格。我们会发现只有右端点在它右边的会造成影响。而这个值就是这些区间最左的左端点。
#include
#include
#include
using namespace std;
const int N=1e5+100;
struct node{
int l,r;
}a[N];
int n,m,ans,Min;
bool cMp(node x,node y)
{return x.r<y.r;}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&a[i].l,&a[i].r);
sort(a+1,a+1+m,cMp);Min=n;
for(int i=m;i>=1;i--){
ans=max(ans,Min-a[i].r);
Min=min(Min,a[i].l);
}
printf("%d",ans);
}
n ∗ m n*m n∗m的图,有一些雷,求每个位置旁边有多少雷
暴力模拟不解释
#include
#include
#include
using namespace std;
int a[1002][1002],n,m;
int main()
{
//freopen("mine.in","r",stdin);
//freopen("mine.out","w",stdout);
scanf("%d%d\n",&n,&m);
string s;
for (int x=1;x<=n;x++)
{
getline(cin,s);
for (int y=0;y<m;y++)
{
if (s[y]=='*')
{
for (int i=x-1;i<=x+1;i++)
for (int j=y-1;j<=y+1;j++)
{
if (i>=0 && j>=0 && i<=n && j<=m && a[i][j+1]!=23333)
a[i][j+1]++;
}
a[x][y+1]=23333;
}
}
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
if (a[i][j]==23333) printf("%c",'*');
else printf("%d",a[i][j]);
printf("\n");
}
}
n n n个数,求出现次数为奇数的数异或和
若出现次数为偶数,两两异或抵消,所以就是求所有数的异或和
#include
#include
#include
using namespace std;
int n,a,ans;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a),ans^=a ;
printf("%d",ans);
}
加密方法是将字符串每个字符 c c c变为 ( k 1 ∗ c + k 2 ) % 26 (k1*c+k2)\%26 (k1∗c+k2)%26。给一串加密后的,要求解密。
暴力枚举解密后的,然后匹配即可。
#include
#include
#include
#define ll long long
using namespace std;
ll k1,k2,big,a,n;
char s[1100];
int main()
{
scanf("%lld%lld",&k1,&k2);
scanf("%s",s+1);n=strlen(s+1);
for(ll i=1;i<=n;i++){
big=(s[i]<='Z');
a=s[i]-(s[i]<='Z'?'A':'a');
for(ll j=0;j<=25;j++)
if((j*k1+k2)%26ll==a)
{printf("%c",j+(big?'A':'a'));break;}
}
}
一张无向图,每次走两步,求至少增加多少条边可以遍历完整张图
考虑贪心,我们先考虑现在的图联通,我们可以将图分为偶点和奇点。偶点就是可以遍历到的,奇点就是不能的,我们发现若有奇点此时答案为1,否则为0.
那若是分为若干个联通块呢?我们会发现联通块之间无论如何连接并不会影响答案,所以直接暴力连接即可。
#include
#include
#include
using namespace std;
const int N=1e5+100;
struct node{
int to,next;
}a[N*2];
int n,m,ls[N],tot,ans,z,last;
bool v[N][2];
void addl(int x,int y)
{
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;
}
void dfs(int x,int k)
{
if(v[x][k]) return;
v[x][k]=1;
for(int i=ls[x];i;i=a[i].next)
dfs(a[i].to,k^1);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
addl(x,y);addl(y,x);
}
last=1;dfs(1,1);
for(int i=2;i<=n;i++)
if(!v[i][0]&&!v[i][1])
{ans++;dfs(i,1);addl(last,i);last=i;}
memset(v,0,sizeof(v));
dfs(1,1);
for(int i=1;i<=n;i++)
if(!v[i][1])
{ans++;break;}
printf("%d",ans+z);
}
一个序列,每次询问一个区间 [ l , r ] [l,r] [l,r]
∑ i = l r a i ∗ n u m ( a i ) \sum_{i=l}^r a_i*num(a_i) i=l∑rai∗num(ai)
n u m ( a i ) num(a_i) num(ai)表示这个区间中 a i a_i ai的数量
显然的莫队不解释。
#pragma GCC optimize(2)
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
%:pragma GCC optimize("-fgcse")
%:pragma GCC optimize("-fgcse-lm")
%:pragma GCC optimize("-fipa-sra")
%:pragma GCC optimize("-ftree-pre")
%:pragma GCC optimize("-ftree-vrp")
%:pragma GCC optimize("-fpeephole2")
%:pragma GCC optimize("-ffast-math")
%:pragma GCC optimize("-fsched-spec")
%:pragma GCC optimize("unroll-loops")
%:pragma GCC optimize("-falign-jumps")
%:pragma GCC optimize("-falign-loops")
%:pragma GCC optimize("-falign-labels")
%:pragma GCC optimize("-fdevirtualize")
%:pragma GCC optimize("-fcaller-saves")
%:pragma GCC optimize("-fcrossjumping")
%:pragma GCC optimize("-fthread-jumps")
%:pragma GCC optimize("-funroll-loops")
%:pragma GCC optimize("-fwhole-program")
%:pragma GCC optimize("-freorder-blocks")
%:pragma GCC optimize("-fschedule-insns")
%:pragma GCC optimize("inline-functions")
%:pragma GCC optimize("-ftree-tail-merge")
%:pragma GCC optimize("-fschedule-insns2")
%:pragma GCC optimize("-fstrict-aliasing")
%:pragma GCC optimize("-fstrict-overflow")
%:pragma GCC optimize("-falign-functions")
%:pragma GCC optimize("-fcse-skip-blocks")
%:pragma GCC optimize("-fcse-follow-jumps")
%:pragma GCC optimize("-fsched-interblock")
%:pragma GCC optimize("-fpartial-inlining")
%:pragma GCC optimize("no-stack-protector")
%:pragma GCC optimize("-freorder-functions")
%:pragma GCC optimize("-findirect-inlining")
%:pragma GCC optimize("-fhoist-adjacent-loads")
%:pragma GCC optimize("-frerun-cse-after-loop")
%:pragma GCC optimize("inline-small-functions")
%:pragma GCC optimize("-finline-small-functions")
%:pragma GCC optimize("-ftree-switch-conversion")
%:pragma GCC optimize("-foptimize-sibling-calls")
%:pragma GCC optimize("-fexpensive-optimizations")
%:pragma GCC optimize("-funsafe-loop-optimizations")
%:pragma GCC optimize("inline-functions-called-once")
%:pragma GCC optimize("-fdelete-null-pointer-checks")
#include
#include
#include
#include
#define ll long long
using namespace std;
const int N=1e5+100;
struct node{
ll l,r,id,pos;
}a[N];
ll n,m,w[N],l,r,now,id[N],t;
ll cnt[N],ans[N];
bool operator <(node x, node y) {
return x.pos<y.pos||(x.pos==y.pos&&x.r<y.r);
}
inline ll read() {
ll x=0,f=1; char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
}
void print(ll x){
if (x>9) print(x/10); putchar(x%10+48); return;
}
void add(ll x)
{now+=(2*cnt[x]+1)*x;cnt[x]++;}
void del(ll x)
{now-=(2*cnt[x]-1)*x;cnt[x]--;}
int main()
{
n=read();m=read();t=sqrt(n);
for(ll i=1;i<=n;i++)
w[i]=read();
for(ll i=1;i<=m;i++)
a[i].l=read(),a[i].r=read(),a[i].id=i,a[i].pos=(a[i].l-1)/t+1;
sort(a+1,a+1+m);
l=1,r=0;
for(ll i=1;i<=m;i++)
{
while(l>a[i].l) add(w[--l]);
while(r<a[i].r) add(w[++r]);
while(l<a[i].l) del(w[l++]);
while(r>a[i].r) del(w[r--]);
ans[a[i].id]=now;
}
for(ll i=1;i<=m;i++)
print(ans[i]),putchar('\n');
}
c c c种颜色,抽随机 n n n个(每种颜色等概率),求最后是 m m m种颜色个数为奇数的概率
我们设 f i , j f_{i,j} fi,j表示抽到第 i i i个,颜色为 j j j个的方案数,有
f i , j ∗ j c + > f i + 1 , j − 1 f_{i,j}*\frac{j}{c}\ \ \ +>\ \ \ f_{i+1,j-1} fi,j∗cj +> fi+1,j−1
f i , j ∗ c − j c + > f i + 1 , j + 1 f_{i,j}*\frac{c-j}{c}\ \ \ +>\ \ \ f_{i+1,j+1} fi,j∗cc−j +> fi+1,j+1
这个可以用矩阵乘法优化即可。
#include
#include
#include
#define ll long long
using namespace std;
const ll Size=111;
ll n,c,m;
double a[Size][Size],ans[Size][Size],C[Size][Size];
void mulself() {
for(ll i=0;i<=c;i++)
for(ll j=0;j<=c;j++)
C[i][j]=0;
for(ll i=0;i<=c;i++)
for(ll j=0;j<=c;j++)
for(ll k=0;k<=c;k++)
C[i][j]+=a[i][k]*a[k][j];
for(ll i=0;i<=c;i++)
for(ll j=0;j<=c;j++)
a[i][j]=C[i][j];
}
void mul(){
for(ll i=0;i<=c;i++)
for(ll j=0;j<=c;j++)
C[i][j]=0;
for(ll i=0;i<=c;i++)
for(ll j=0;j<=c;j++)
for(ll k=0;k<=c;k++)
C[i][j]+=a[i][k]*ans[k][j];
for(ll i=0;i<=c;i++)
for(ll j=0;j<=c;j++)
ans[i][j]=C[i][j];
}
void ksm(ll b) {
while(b)
{
if(b&1) mul();
mulself();
b>>=1;
}
}
int main()
{
scanf("%lld%lld%lld",&c,&n,&m);
a[0][1]=1;a[c][c-1]=1;
for(ll i=1;i<c;i++)
a[i][i+1]=(double)(c-i)/c,a[i][i-1]=(double)i/c;
for(ll i=0;i<=c;i++)
ans[i][i]=1;
ksm(n);
printf("%.3lf",ans[0][m]);
}
m m m个请求楼层,优先走到最高层的,求要多久才接到 k k k楼
在所有读入的数中求一个最大值 h h h,然后答案就是 2 h − 1 − k 2h-1-k 2h−1−k
#include
#include
#include
using namespace std;
int n,k,maxs,num;
int main()
{
scanf("%d%d",&n,&k);
maxs=k;
for(int i=1;i<=n;i++){
scanf("%d",&num);
maxs=max(maxs,num);
}
printf("%d",maxs-1+maxs-k);
}
一序列中有的空缺了,求有多少种填数方式使得这是一个单调不降序列
我们发现若一段连续的空缺 l l l,且这段空缺中可以填的数的个数为 k k k,那么这段空缺的方案数就是 C k + l − 1 l − 1 C^{l-1}_{k+l-1} Ck+l−1l−1(插板法)。然后计算方案数即可。
#include
#include
#include
#define ll long long
using namespace std;
const ll XJQ=1e9+7,N=2e6+100;
ll num[N],n,ans=1,last=1000,z,inv[N];
ll C(ll n,ll m)
{
if(n<m) return 0;
ll ans=1;
for(ll i=1;i<=m;i++)
ans=ans*((n-i+1)%XJQ)%XJQ*inv[i]%XJQ;
return ans;
}
int main()
{
scanf("%lld",&n);
inv[1]=1;
for(ll i=2;i<=N;i++)
inv[i]=inv[XJQ%i]*(XJQ-XJQ/i)%XJQ;
for(ll i=1;i<=n;i++){
scanf("%lld",&num[i]);
if(num[i]){
(ans*=C(last-num[i]+i-z-1,i-z-1))%=XJQ;
last=num[i];z=i;
}
}
(ans*=C(last-1+n-z,n-z))%=XJQ;
printf("%lld",ans);
}