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;
}