gyx的NOIP膜你赛

gyx的NOIP模拟赛

我不应该相信自己的暴力的呜呜呜

A Sum

幼稚园水题都没A掉 还是太菜了

题意:多组数据,给出一个区间,求区间内满足\(a+b=c\)的三元组\((a,b,c)\)个数

写的\(O(n)\)做法丢人

想出来了这个

\[\sum_{i=l}^{2i\leq r}[2(r-2i)+1] \]

然后这TM是个等差数列啊

\[(2r-2l-2\cdot \lfloor \frac{r}{2}\rfloor+1)(\lfloor \frac{r}{2}\rfloor-l+1) \]

注意要特判(\(O(n)\)做法不需要特判很好但是\(O(n)\)过不了

码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll l,r,ans=0,t;

int main(){
    
	cin>>t;
	
	while(t--){
		ans=0;
		scanf("%lld%lld",&l,&r);
		if(2*l>r){printf("0\n");continue;}
		ans=(2*r-2*l-2*(r/2)+1)*((r/2)-l+1);
		printf("%lld\n",ans);
	}
    
	return 0;
}

B Vote

贪 心 贪 爆 了

题意:懂王和睡王的大选 给出\(n\)个数对\((a,b)\),现在要求\(ans1\)\(ans2\)满足存在一种情况使得\(ans1\)个数对的\(a+b\)之和大于其余数对的\(b\)之和,\(ans2\)个数对的\(a+b\)之和大于其余数对的\(a\)之和

简化后的题意可以容易看出每个数对,对于\(ans1\)的收益是\(a+2b\),对于\(ans2\)的收益是\(2a+b\),可以按这两个收益排两个序,然后扫一遍,用支持sk和kk的总人数,比较一下就行了

码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1000007;

ll s1[N],s2[N],as,bs,ans1,ans2,n;

inline int rd() {
  int x = 0;
  bool f = 0;
  char c = getchar();
  for (; !isdigit(c); c = getchar()) if (c == '-') f = 1;
  for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
  return f ? -x : x;
}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		ll a=rd();
		ll b=rd();
		as+=a;
		bs+=b;
		s1[i]=a+2*b;
		s2[i]=a*2+b;
	}
	sort(s1+1,s1+1+n);
	sort(s2+1,s2+1+n);
	for(int i=n;i;i--){
		if(bs>=0) bs-=s1[i],ans1++;
		if(as>=0) as-=s2[i],ans2++;
	}
	
	printf("%lld %lld\n", ans1, ans2);
	
	return 0;
}

C Chess

别骂了别骂了 我就会抄板子

题意:车走直,马走日,象走田,给定一个棋子和它的初始位置,问它走k步能走出多少条路径,多组数据

矩阵乘法板子题 主要在建图(调了2h

码(蒟蒻的建图方法:

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=110,Mod=19260817;

int t,a,b,c,dw,e;

struct Matrix{
	int m,n;
	int a[N][N];
	
	inline void init(int _m=0,int _n=0){
		m=_m;n=_n;
		memset(a,0,sizeof a);
	}
	
	inline Matrix operator * (Matrix B){
		Matrix res;
		res.init(m,B.n);
		for(int i=1;i<=m;i++)
			for(int j=1;j<=B.m;j++)
				for(int k=1;k<=n;k++)
					(res.a[i][j]+=a[i][k]*B.a[k][j])%=Mod;
		return res;
	}
	
	inline void id(){
		for(int i=1;i<=m;i++) a[i][i]=1;
	}
	
	inline Matrix fpow(int t){
		Matrix res;
		res.init(m,m);
		res.id();
		Matrix tmp=*this;
		for(;t;t>>=1,tmp=tmp*tmp) if(t&1) res=res*tmp;
		return res;
	}
	
	
};

void work1(){
	Matrix d;
	d.init(a*b,a*b);
	
	for(int i=1;i<=a*b;i++){
		for(int j=i;j<=a*b;j++){
			if((i-1)/b==(j-1)/b) d.a[i][j]=d.a[j][i]=1;
			else if(i%b==j%b) d.a[i][j]=d.a[j][i]=1;
			if(i==j) d.a[i][j]=0;
		}
	}
	
	Matrix res;
	res=d.fpow(e);
	int ans=0;
	int sta=(c-1)*b+dw;
	for(int i=1;i<=a*b;i++)
		ans=(ans+res.a[sta][i])%Mod;
	cout<<ans%Mod<<endl;
	
	return;
}

void work2(){
	Matrix d;
	d.init(a*b,a*b);
	
	for(int i=1;i<=a*b;i++){
		int y1=(i-1)/b+1,x1=i%b==0?b:i%b;
		if(x1-2>0&&y1-1>0) d.a[i][i-2-b]=d.a[i-2-b][i]=1;
		if(x1-2>0&&y1+1<=a) d.a[i][i-2+b]=d.a[i-2+b][i]=1;
		if(x1+2<=b&&y1-1>0) d.a[i][i+2-b]=d.a[i+2-b][i]=1;
		if(x1+2<=b&&y1+1<=a) d.a[i][i+2+b]=d.a[i+2+b][i]=1;
		if(x1-1>0&&y1-2>0) d.a[i][i-1-2*b]=d.a[i-1-2*b][i]=1;
		if(x1+1<=b&&y1-2>0) d.a[i][i+1-2*b]=d.a[i+1-2*b][i]=1;
		if(x1+1<=b&&y1+2<=a) d.a[i][i+1+2*b]=d.a[i+1+2*b][i]=1;
		if(x1-1>0&&y1+2<=a) d.a[i][i-1+2*b]=d.a[i-1+2*b][i]=1;
	}
    
    //没错hin恶心
	
	Matrix res;
	res=d.fpow(e);
	int ans=0;
	int sta=(c-1)*b+dw;
	for(int i=1;i<=a*b;i++)
		ans=(ans+res.a[sta][i])%Mod;
	cout<<ans%Mod<<endl;
	
	return;
}

void work3(){
	Matrix d;
	d.init(a*b,a*b);
	
	for(int i=1;i<=a*b;i++){
		int y1=(i-1)/b+1,x1=i%b==0?b:i%b;
		if(x1-2>0&&y1-2>0) d.a[i][i-2-2*b]=d.a[i-2-2*b][i]=1;
		if(x1-2>0&&y1+2<=a) d.a[i][i-2+2*b]=d.a[i-2+2*b][i]=1;
		if(x1+2<=b&&y1-2>0) d.a[i][i+2-2*b]=d.a[i+2-2*b][i]=1;
		if(x1+2<=b&&y1+2<=a) d.a[i][i+2+2*b]=d.a[i+2+2*b][i]=1;
	}
	
	Matrix res;
	res=d.fpow(e);
	int ans=0;
	int sta=(c-1)*b+dw;
	for(int i=1;i<=a*b;i++)
		ans=(ans+res.a[sta][i])%Mod;
	cout<<ans%Mod<<endl;
	
	return;
}

signed main(){
	
	cin>>t;
	while(t--){
		int k;
		cin>>k;
		cin>>a>>b;
		cin>>c>>dw>>e;
		if(k==0) work1();
		else if(k==1) work2();
		else work3();
	}
	
	return 0;
}

码(dalao的建图方法:

#include <bits/stdc++.h>
#define N 107
#define mod 19260817
using namespace std;
typedef long long ll;

inline ll rd() {
    ll x = 0;
    bool f = 0;
    char c = getchar();
    for(; !isdigit(c); c = getchar()) 
        if (c == '-') f = 1;
    for(; isdigit(c); c = getchar())
        x = x * 10 + (c ^ 48);
    return f ? -x : x;
}

struct matrix {
  
  int m, n;
  
  int a[N][N];

  inline void init(int _m = 0, int _n = 0) {
    m = _m; n = _n;
    memset(a, 0, sizeof(a));
  }

  inline matrix operator * (matrix B) {
    matrix res;
    res.init(m, B.n);
    for (int i = 1; i <= m; ++i)
      for (int j = 1; j <= B.m; ++j)
        for (int k = 1; k <= n; ++k)
          res.a[i][j] = (res.a[i][j] + 1ll * a[i][k] * B.a[k][j] % mod) % mod; 
    return res;
  }

  inline void id() {
    for (int i = 1; i <= m; ++i) a[i][i] = 1;
  }

  inline matrix fpow(ll t) {
    matrix res; 
    res.init(n, n); res.id();
    matrix tmp = *this;
    for(; t; t >>= 1, tmp = tmp * tmp)
      if (t & 1) res = res * tmp;
    return res;
  }

}S;

int n, m;

int pos(int x, int y) {
  return x + (y - 1) * n;
}

inline void build_rook() {
  for (int x = 1; x <= n; ++x)
    for (int y = 1; y <= m; ++y) {
      int nw = pos(x, y);
      for (int i = 1; i <= n; ++i)
        if (i != x) {
          int t = pos(i, y);
          ++S.a[nw][t]; 
        }
      for (int i = 1; i <= m; ++i) 
        if (i != y) {
          int t = pos(x, i);
          ++S.a[nw][t];
        }
    }
}

//gyxnb!!!!

const int dx[8] = {2, 2, 1, 1, -1, -1, -2, -2};

const int dy[8] = {1, -1, 2, -2, 2, -2, 1, -1};

inline void build_knight() {
  for (int x = 1; x <= n; ++x)
    for (int y = 1; y <= m; ++y) {
      int nw = pos(x, y);
      for (int i = 0; i <= 7; ++i) {
          int tx = x + dx[i];
          int ty = y + dy[i];
          if (tx <= 0 || ty <= 0 || tx > n || ty > m) continue; 
          int t = pos(tx, ty);
          ++S.a[nw][t];
        }
    }
}

const int Dx[4] = {2, 2, -2, -2};

const int Dy[4] = {2, -2, 2, -2};

inline void build_bishop() {
  for (int x = 1; x <= n; ++x)
    for (int y = 1; y <= m; ++y) {
      int nw = pos(x, y);
      for (int i = 0; i <  4; ++i) {
          int tx = x + Dx[i];
          int ty = y + Dy[i];
          if (tx <= 0 || ty <= 0 || tx > n || ty > m) continue; 
          int t = pos(tx, ty);
          ++S.a[nw][t];
        }
    }
}

inline void work() {
  int op = rd();
  n = rd(); m = rd();
  S.init(n * m, n * m);
  int sx = rd(); 
  int sy = rd();
  if (op == 0) build_rook();
  if (op == 1) build_knight();
  if (op == 2) build_bishop();
  S = S.fpow(rd());
  ll ans = 0;
  int s = pos(sx, sy);
  for (int i = 1; i <= n * m; ++i)
    ans = (ans + S.a[s][i]) % mod;
  printf("%lld\n", ans);
}

int main() {
    freopen("chess.in", "r", stdin);
    freopen("chess.out", "w", stdout);
    int t = rd();
    while (t--) work();
    fclose(stdin);
    fclose(stdout);
    return 0;
}

D Number

题意:给一个P进制数,支持修改某一区间上的数字,最后用十进制表示出来,多组数据

呜呜呜线段树啊

维护某一位上的数乘上p的幂就行了

用前缀和改区间值

码:

#include<bits/stdc++.h>
#define ll long long
#define mid ((l+r)>>1)
using namespace std;
const int N=500007,Mod=19260817;

inline ll rd() {
    ll x = 0;
    bool f = 0;
    char c = getchar();
    for(; !isdigit(c); c = getchar()) 
        if (c == '-') f = 1;
    for(; isdigit(c); c = getchar())
        x = x * 10 + (c ^ 48);
    return f ? -x : x;
}

ll t[N],a[N],n,tag[N],pw[N],spw[N];

void pushup(int x){
    t[x]=(t[x<<1]+t[x<<1|1])%Mod;
}

void build(int x,int l,int r){
    if(l==r) return t[x]=1ll*a[l]*pw[l]%Mod,void();
    tag[x]=-1;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    pushup(x);
}
void pushdown(int x,int l,int r){
    if(tag[x]!=-1){
        tag[x<<1] = tag[x];
  		t[x<<1] = 1ll * tag[x] * (spw[mid] - spw[l - 1] + Mod) % Mod;
  		tag[x<<1|1] = tag[x];
  		t[x<<1|1] = 1ll * tag[x] * (spw[r] - spw[mid] + Mod) % Mod;
  		tag[x] = -1;
    }
}
void change(int x,int l,int r,int cl,int cr,int dlt){
    if(cl<=l&&r<=cr){
		tag[x]=dlt;
		t[x]=1ll*dlt*(spw[r]-spw[l-1]+Mod)%Mod;
		return;
	}
	pushdown(x,l,r);
    if(cl<=mid) change(x<<1,l,mid,cl,cr,dlt);
    if(cr>=mid+1) change(x<<1|1,mid+1,r,cl,cr,dlt);
    pushup(x);
}

int main(){
	
	int n=rd();
	int p=rd();
	int m=rd();
	spw[1]=pw[1]=1;
	for(int i=1;i<=n;i++){
		a[n-i+1]=rd();
		pw[i+1]=1ll*pw[i]*p%Mod;
		spw[i+1]=(spw[i]+pw[i+1])%Mod;
	}
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int r=n-rd()+1;
		int l=n-rd()+1;
		int x=rd();
		change(1,1,n,l,r,x);
		printf("%d\n",t[1]);
	}
	
	return 0;
}
posted @ 2021-02-27 15:35  wsy_jim  阅读(91)  评论(0编辑  收藏  举报