版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37960603/article/details/84628647
A
被砸到的概率 = 1 - 不被砸到的概率
而不被砸到的概率很容易计算。
代码:
#include<cstdio>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=100000+100;
ll mypow(ll a,ll b){
ll sum=1;
while(b){
if(b&1) sum=sum*a%mod;
a=a*a%mod;
b>>=1;
}
return sum;
}
ll fz[maxn],fm[maxn];
int main(){
int n;
scanf("%d",&n);
ll ans=1;
for(int i=1;i<=n;i++){
scanf("%lld%lld",&fz[i],&fm[i]);
ll tmp=mypow(fm[i],mod-2);
ans=(ans*(fm[i]-fz[i])%mod*tmp)%mod;
}
printf("%lld\n",(1-ans+mod)%mod);
}
B
代码:
#include<cstdio>
using namespace std;
int main(){
int T;
scanf("%d",&T);
while(T--){
long long n;
scanf("%lld",&n);
if(n<=2) printf("1\n");
else printf("0\n");
}
}
C
线段树很容易做出来。
代码:
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn=100000+100;
struct Tree{
ll val;
int Xor;
int num;
int bit[20];
}tree[maxn<<2];
int val[maxn];
void build(int rt,int l,int r){
if(l==r){
for(int i=0;i<20;i++) if((val[l]>>i)&1) tree[rt].bit[i]=1;
tree[rt].val=val[l];
tree[rt].num=1;
tree[rt].Xor=0;
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
for(int i=0;i<20;i++) tree[rt].bit[i]=(tree[rt<<1].bit[i]+tree[rt<<1|1].bit[i]);
tree[rt].num=(r-l+1);
tree[rt].Xor=0;
tree[rt].val=(tree[rt<<1].val+tree[rt<<1|1].val);
}
void updateDown(int rt,int l,int r,int mid){
int Xor=tree[rt].Xor;
tree[rt<<1].Xor^=Xor;
tree[rt<<1|1].Xor^=Xor;
for(int i=0;i<20;i++){
if((Xor>>i)&1){
tree[rt<<1].bit[i]=tree[rt<<1].num-tree[rt<<1].bit[i];
tree[rt<<1|1].bit[i]=tree[rt<<1|1].num-tree[rt<<1|1].bit[i];
}
}
if(l==mid) tree[rt<<1].val^=Xor;
else{
tree[rt<<1].val=0;
for(int i=0;i<20;i++) tree[rt<<1].val+=((1LL*tree[rt<<1].bit[i])<<i);
}
if(mid+1==r) tree[rt<<1|1].val^=Xor;
else{
tree[rt<<1|1].val=0;
for(int i=0;i<20;i++) tree[rt<<1|1].val+=((1LL*tree[rt<<1|1].bit[i])<<i);
}
tree[rt].Xor=0;
}
void update(int rt,int l,int r,int L,int R,int Xor){
if(L<=l && R>=r){
tree[rt].Xor^=Xor;
for(int i=0;i<20;i++){
if((Xor>>i)&1){
tree[rt].bit[i]=tree[rt].num-tree[rt].bit[i];
}
}
tree[rt].val=0;
for(int i=0;i<20;i++) tree[rt].val+=((1LL*tree[rt].bit[i])<<i);
return ;
}
int mid=(l+r)>>1;
if(tree[rt].Xor) updateDown(rt,l,r,mid);
if(L<=mid) update(rt<<1,l,mid,L,R,Xor);
if(R>mid) update(rt<<1|1,mid+1,r,L,R,Xor);
for(int i=0;i<20;i++) tree[rt].bit[i]=(tree[rt<<1].bit[i]+tree[rt<<1|1].bit[i]);
tree[rt].val=(tree[rt<<1].val+tree[rt<<1|1].val);
}
ll query(int rt,int l,int r,int L,int R){
if(L>r || R<l) return 0;
if(L<=l && R>=r) return tree[rt].val;
int mid=(l+r)>>1;
if(tree[rt].Xor) updateDown(rt,l,r,mid);
return query(rt<<1,l,mid,L,R)+query(rt<<1|1,mid+1,r,L,R);
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
build(1,1,n);
for(int i=1;i<=m;i++){
int type,l,r,k;
scanf("%d",&type);
if(type==1){
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,1,n,l,r));
}
else{
scanf("%d%d%d",&l,&r,&k);
if(k) update(1,1,n,l,r,k);
}
}
}
D
由于都是在某一棵子树上操作,所以并不一定需要使用树链剖分,只要根据树链剖分的思想进行重编号,记录每棵子树的编号范围即可,再用线段树维护。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=100000+100;
const int mod=23333;
struct Tree{
ll add;
ll two;
ll mul;
}tree[maxn<<2];
int id[maxn],maxid[maxn],rev[maxn],id_cnt;
bool vis[maxn];
struct Edge{
int to,next;
}edge[maxn<<1];
int head[maxn],tot;
int val[maxn];
void init(){
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
tot=id_cnt=0;
}
void addEdge(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
edge[tot].to=u;
edge[tot].next=head[v];
head[v]=tot++;
}
void dfs(int u){
vis[u]=true;
id[u]=maxid[u]=(++id_cnt);
rev[id_cnt]=u;
for(int i=head[u];i!=-1;i=edge[i].next){
Edge e=edge[i];
if(!vis[e.to]){
dfs(e.to);
maxid[u]=max(maxid[u],maxid[e.to]);
}
}
}
void build(int rt,int l,int r){
if(l==r){
int v=val[rev[l]];
tree[rt].mul=v;
tree[rt].two=v*v;
tree[rt].add=0;
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
tree[rt].mul=(tree[rt<<1].mul+tree[rt<<1|1].mul);
tree[rt].two=(tree[rt<<1].two+tree[rt<<1|1].two);
tree[rt].mul%=mod;
tree[rt].two%=mod;
tree[rt].add=0;
}
void updateDown(int rt,int l,int r,int mid){
ll Add=tree[rt].add;
tree[rt<<1].add+=Add;
tree[rt<<1|1].add+=Add;
tree[rt<<1].two+=((mid-l+1)*Add*Add+tree[rt<<1].mul*2*Add);
tree[rt<<1|1].two+=((r-mid)*Add*Add+tree[rt<<1|1].mul*2*Add);
tree[rt<<1].mul+=((mid-l+1)*Add);
tree[rt<<1|1].mul+=((r-mid)*Add);
tree[rt<<1].add%=mod;
tree[rt<<1|1].add%=mod;
tree[rt<<1].mul%=mod;
tree[rt<<1|1].mul%=mod;
tree[rt<<1].two%=mod;
tree[rt<<1|1].two%=mod;
tree[rt].add=0;
}
void update(int rt,int l,int r,int L,int R,int v){
if(L<=l && R>=r){
tree[rt].add+=v;
tree[rt].two+=(1LL*(r-l+1)*v*v+tree[rt].mul*2*v);
tree[rt].mul+=(1LL*(r-l+1)*v);
tree[rt].add%=mod;
tree[rt].mul%=mod;
tree[rt].two%=mod;
return ;
}
int mid=(l+r)>>1;
if(tree[rt].add) updateDown(rt,l,r,mid);
if(L<=mid) update(rt<<1,l,mid,L,R,v);
if(R>mid) update(rt<<1|1,mid+1,r,L,R,v);
tree[rt].mul=(tree[rt<<1].mul+tree[rt<<1|1].mul);
tree[rt].two=(tree[rt<<1].two+tree[rt<<1|1].two);
tree[rt].mul%=mod;
tree[rt].two%=mod;
}
int query(int rt,int l,int r,int L,int R){
if(L>r || R<l) return 0;
if(L<=l && R>=r) return tree[rt].two;
int mid=(l+r)>>1;
if(tree[rt].add) updateDown(rt,l,r,mid);
return (query(rt<<1,l,mid,L,R)+query(rt<<1|1,mid+1,r,L,R))%mod;
}
int main(){
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&val[i]),val[i]%=mod;
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
addEdge(u,v);
}
dfs(1);
build(1,1,n);
for(int i=1;i<=m;i++){
int type,x,y;
scanf("%d",&type);
if(type==1){
scanf("%d%d",&x,&y);
//printf("%d %d\n",id[x],maxid[x]);
y%=mod;
update(1,1,n,id[x],maxid[x],y);
}
else{
scanf("%d",&x);
printf("%d\n",query(1,1,n,id[x],maxid[x]));
}
}
}
E
只需要记录 <= x 的 a[i] 信息,所以先排序,位置信息由树状数组来维护。
代码:
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100000+100;
int n,m;
struct Node{
int l,r,id,val;
bool operator <(const Node a)const{
return a.val>val;
}
}node[maxn];
struct Val{
int id,val;
bool operator <(const Val a)const{
return a.val>val;
}
}val[maxn];
int ans[maxn];
int tree[maxn];
int getSum(int x){
int sum=0;
while(x>0){
sum+=tree[x];
x-=(x&(-x));
}
return sum;
}
void update(int x){
while(x<=n){
tree[x]++;
// printf("%d %d\n",tree[x],x);
x+=(x&(-x));
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&val[i].val),val[i].id=i;
for(int i=1;i<=m;i++) scanf("%d%d%d",&node[i].l,&node[i].r,&node[i].val),node[i].id=i;
sort(val+1,val+n+1);
sort(node+1,node+m+1);
for(int i=1,j=1;i<=m;i++){
for(;j<=n && node[i].val>=val[j].val;j++){
update(val[j].id);
//printf("%d %d %d\n",node[i].val,val[j].val,val[j].id);
}
//printf("%d\n",getSum(node[i].r));
ans[node[i].id]=getSum(node[i].r)-((node[i].l==1)?0:getSum(node[i].l-1));
}
for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
}
H
代码:
#include<cstdio>
using namespace std;
int main(){
long long n;
scanf("%lld",&n);
if(n!=1) printf("%lld\n",n+(n-1));
else printf("2\n");
}