A-病毒感染
题意给一颗树,然后要求这个树上到所有点权值最小的那个点。实际上这个点就是树的重心,直接去求树的重心就可以了。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+50;
struct node {
int v,next;
}e[maxn];
int cnt=0,front[maxn],d[maxn],f[maxn],mmin=0x3f3f3f3f;
int n,m;
inline void addedge(int u,int v) {
e[++cnt].v=v;
e[cnt].next=front[u];
front[u]=cnt;
}
void dfs(int u,int fa)
{
d[u]=1,f[u]=0;
for(int i=front[u];i;i=e[i].next) {
int v=e[i].v;
if(v==fa) continue;
dfs(v,u);
d[u]+=d[v];
f[u]=max(f[u],d[v]);
}
f[u]=max(f[u],n-d[u]);
mmin=min(mmin,f[u]);
}
int main()
{
int u,v;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i) {
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
dfs(1,0);
for(int i=1;i<=n;++i)
if(f[i]==mmin)
printf("%d ",i);
}
B-切题之路
这个只要理解题目然后模拟即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e5+50;
struct node
{
ll tim,le;
}p[maxn];
int main()
{
ll n,t,a,b,rqy=0,clccle=0;
scanf("%lld%lld%lld%lld",&n,&t,&a,&b);
ll rqyt=t;ll clcclet=t;
for(ll i=1;i<=n;++i) scanf("%lld",&p[i].tim);
for(ll i=1;i<=n;++i) scanf("%lld",&p[i].le);
for(ll i=1;i<=n;++i)
{
if(p[i].le<a&&clcclet>=p[i].tim) clccle++,clcclet-=p[i].tim;
if(p[i].le>=b&&rqyt>=p[i].tim*2) rqy++,rqyt-=2*p[i].tim;
if(p[i].le<b&&rqyt>=p[i].tim) rqy++,rqyt-=p[i].tim;
}
printf("%lld %lld\n",clccle,rqy);
return 0;
}
C-神秘钥匙
直接考虑求 求出答案即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll fastpow(ll x , ll y)
{
ll ans=1;
while(y)
{
if(y&1) (ans*=x)%=mod;
(x*=x)%=mod;
y/=2;
}
return ans%mod;
}
int main()
{
ll n;
scanf("%lld",&n);
printf("%lld",(n%mod*fastpow(2,n-1))%mod);
}
D-迷之盒子
首先我们先考虑如果没有条件约束的情形,所有得情形应当为 ,然后我们找出这里面所有不符合得情形的数目,我们考虑吧剩下的先划分成不合法的个数是 答案就是两者相减即可,由于数据量比较大要用到Lucas定理来求解
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
ll fpow(ll x,ll y)
{
ll ans=1;
while(y) {
if(y&1) (ans*=x)%=mod;
(x*=x)%=mod;
y/=2;
}
return ans%mod;
}
ll cal(ll n,ll m) {
ll ans=1;
for(int i=1;i<=m;++i){
ll t1=(n-m+i)%mod;
ll t2=i%mod;
ans=ans*(t1*fpow(t2,mod-2)%mod)%mod;
}
return ans%mod;
}
ll lucas(ll n,ll m) {
if(m==0) return 1;
return cal(n%mod,m%mod) *lucas(n/mod,m/mod) %mod;
}
int main()
{
ll n,m,k,ans=0;
scanf("%lld%lld%lld",&n,&m,&k);
ll sum=lucas(n+m-1,n-1);
ll upper=m/(k+1);
for(ll i=1;i<=upper;++i)
(ans+=lucas(n,i)*lucas(m+n-i*(k+1)-1,n-1)%mod)%=mod;
printf("%lld\n",sum-ans);
return 0;
}
E-诡异数字
注意到是对一个区间里面判断数字性质的问题,很容易联想到数位dp.我们一个四维参数dfs,分别保存当前的数位,前面的数位是否被限定,前驱,以及前驱重复的个数.然后就可以开始胡乱转移了
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int maxn=20;
const int mod=20020219;
int limit[maxn],len[maxn],f[maxn][11];
ll dfs(int pos,bool islimit,int pre,int sum)
{
if(sum>limit[pre]) return 0;
if(pos==0) return 1;
if(!islimit&&f[pos][pre]!=-1) return f[pos][pre];
int up=islimit?len[pos]:9;
int temp=0;
for(int i=0;i<=up;i++)
temp+=dfs(pos-1,islimit&&i==len[pos],i,i==pre?sum+1:1);
return islimit?temp:f[pos][pre]=temp;
}
ll solve(ll sum)
{
if(sum==-1) return 0;
int cnt=0;
while(sum){
len[++cnt]=sum%10;
sum/=10;
}
ll ans=0;
for(int i=0;i<=len[cnt];++i)
(ans+=dfs(cnt-1,i==len[cnt],i,1))%=mod;
return ans%mod;
}
signed main()
{
int line;
scanf("%lld",&line);
for(int i=1;i<=line;i++)
{
memset(f,-1,sizeof(f));
memset(limit,0x3f3f3f,sizeof(limit));
ll l,r;int n;
scanf("%lld%lld%lld",&l,&r,&n);
for(int t=1;t<=n;++t){
int x,len;
scanf("%lld%lld",&x,&len);
limit[x]=min(limit[x],len);
}
printf("%lld\n",(solve(r)-solve(l-1)+mod)%mod);
}
}
F-数列操作
裸的平衡树
#include<cstdio>
#include<algorithm>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define gc getchar()
using namespace std;
const int N=400011;
int n,p;
int a[N],b[N],c[N];
namespace Segment_Tree{
int tr[N];
inline void modify(int x,int v,int k=1,int l=1,int r=c[0]){
tr[k]+=v;
if(l==r)return ;
int mid=(l+r)>>1;
x<=mid?modify(x,v,ls):modify(x,v,rs);
}
inline int query_num(int x,int k=1,int l=1,int r=c[0]){
if(l==r)return l;
int mid=(l+r)>>1;
return x<=tr[k<<1]?query_num(x,ls):query_num(x-tr[k<<1],rs);
}
inline int query_pos(int x,int type,int k=1,int l=1,int r=c[0]){
if(l==r){
if(type==3)return 1;
if(type==5)return 0;
if(type==6)return tr[k]+1;
}
int mid=(l+r)>>1;
return x<=mid?query_pos(x,type,ls):(tr[k<<1]+query_pos(x,type,rs));
}
}
using namespace Segment_Tree;
inline void disc_init(){
sort(c+1,c+c[0]+1);
c[0]=unique(c+1,c+c[0]+1)-c-1;
FOR(i,1,n)
if(a[i]!=4)b[i]=lower_bound(c+1,c+c[0]+1,b[i])-c;
}
inline int read(){
char c;while(c=gc,c==' '||c=='\n');int data=0,f=1;
c=='-'?f=-1:data=c-48;
while(c=gc,c>='0'&&c<='9')data=(data<<1)+(data<<3)+c-48;
return data*f;
}
int main(){
n=read();
FOR(i,1,n){
a[i]=read();b[i]=read();
if(a[i]!=4)c[++c[0]]=b[i];
}
disc_init();
FOR(i,1,n){
if(a[i]==1)modify(b[i],1);
if(a[i]==2)modify(b[i],-1);
if(a[i]==3)printf("%d\n",query_pos(b[i],3));
if(a[i]==4)printf("%d\n",c[query_num(b[i])]);
if(a[i]==5)printf("%d\n",c[query_num(query_pos(b[i],5))]);
if(a[i]==6)printf("%d\n",c[query_num(query_pos(b[i],6))]);
}
return 0;
}
红包期望
简单的概率论问题,根据全期望公式知道前面m个人先后取值是无所谓的都是都是 ,而后面m个人的期望全部是0.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double ld;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ini(a,x) memset(a,x,sizeof(a))
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const ld pi=acos(-1);
const ld eps=1e-9;
void read(int &x)
{
x=0; int f=1; char ch=getchar();
while (ch<'0'||ch>'9') { if (ch=='-')f=-1; ch=getchar(); }
while (ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
x=x*f;
}
int main()
{
ll m,n,T;
scanf("%lld%lld%lld",&m,&n,&T);
while(T--)
{
ll t;
scanf("%lld",&t);
if(t<=m) printf("%lld\n",n/m);
else printf("0\n");
}
return 0;
}
H-机房网络
据说是网络流+线段树维护,目前还是知识盲区
I-路灯孤影
似乎是一个很难的dp,虽然队友一度坚持可以暴力剪枝来做qwq
J-好的序列
Rqy的毒瘤题,不知道谁会,反正我不会