T1 以前做过的原题 GSS3。线段树。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN = 500005;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,m,a[MAXN];
struct Node{
int mx,lx,rx,sum;
}node[MAXN<<2];
inline void pushup(int x){
node[x].sum=node[x<<1].sum+node[x<<1|1].sum;
node[x].lx=max(node[x<<1].lx,node[x<<1].sum+node[x<<1|1].lx);
node[x].rx=max(node[x<<1|1].rx,node[x<<1|1].sum+node[x<<1].rx);
node[x].mx=max(node[x<<1|1].mx,max(node[x<<1].mx,node[x<<1].rx+node[x<<1|1].lx));
}
inline void build(int x,int l,int r){
if(l==r){
node[x].sum=node[x].lx=node[x].rx=node[x].mx=a[l];
return ;
}
int mid=l+r>>1;
build(x<<1,l,mid);build(x<<1|1,mid+1,r);
pushup(x);
}
inline Node query(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return node[x];
int mid=l+r>>1;
if(mid<L) return query(x<<1|1,mid+1,r,L,R);
if(mid>=R) return query(x<<1,l,mid,L,R);
else{
Node A=query(x<<1,l,mid,L,R);
Node B=query(x<<1|1,mid+1,r,L,R);
Node ans;
ans.sum=A.sum+B.sum;
ans.lx=max(A.lx,A.sum+B.lx);
ans.rx=max(B.rx,B.sum+A.rx);
ans.mx=max(max(A.mx,B.mx),A.rx+B.lx);
return ans;
}
}
inline void update(int x,int l,int r,int L,int R,int k){
if(l==r && l==L){
node[x].sum=node[x].mx=node[x].lx=node[x].rx=k;
return;
}
int mid=l+r>>1;
if(mid>=L) update(x<<1,l,mid,L,R,k);
if(mid<R) update(x<<1|1,mid+1,r,L,R,k);
pushup(x);
}
int main(){
freopen("BRS.in","r",stdin);
freopen("BRS.out","w",stdout);
n=rd();m=rd();
for(register int i=1;i<=n;i++) a[i]=rd();
build(1,1,n);
for(register int i=1;i<=m;i++){
int op=rd(),x=rd(),y=rd();
if(op==1) printf("%d
",query(1,1,n,x,y).mx);
else update(1,1,n,x,x,y);
}
return 0;
}
T2打表找规律,最后发现是一个类似斐波那契的,矩阵乘法直接搞。结果考场上最后一步没有取模爆零?????233333.。。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
const int mod = 7777777;
int n,k;
struct Mat{
LL a[15][15];
Mat(){
memset(a,0,sizeof(a));
}
Mat operator*(const Mat &h){
Mat c;
for(register int i=1;i<=k;i++)
for(register int j=1;j<=k;j++)
for(register int o=1;o<=k;o++)
(c.a[i][j]+=(a[i][o]%mod*h.a[o][j]%mod))%=mod;
return c;
}
}f,ans,st;
inline void fast_pow(Mat A,int b){
for(;b;b>>=1){
if(b&1) st=st*A;
A=A*A;
}
}
int main(){
freopen("fyfy.in","r",stdin);
freopen("fyfy.out","w",stdout);
scanf("%d%d",&k,&n);
if(k==1){
puts("1");
return 0;
}
for(register int i=2;i<=k;i++) f.a[i][i-1]=1;
for(register int i=1;i<=k;i++) f.a[i][k]=1;
for(register int i=1;i<=k;i++) st.a[i][i]=1;
fast_pow(f,n);
printf("%lld
",st.a[k][k]);
return 0;
}
T3,扫描线。。当时的坑没填,暴力30分走人。先把纵坐标离散化,之后将横坐标排序,然后一个个的跳。因为数据范围小,直接O(n^2) 能过,就没线段树优化。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define int long long
using namespace std;
const int MAXN = 105;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n;
struct Node{
int x1,x2,y1,y2;
}node[MAXN];
struct A{
int y1,y2,x,k;
}a[MAXN<<1];
int y[MAXN<<1],cnt;
int c[MAXN<<1];
LL ans;
inline bool cmp(A a,A b){
return a.x<b.x;
}
signed main(){
freopen("olddriver.in","r",stdin);
freopen("olddriver.out","w",stdout);
n=rd();
for(register int i=1;i<=n;i++){
node[i].x1=rd(),node[i].y1=rd();
node[i].x2=rd(),node[i].y2=rd();
y[++cnt]=node[i].y1;
y[++cnt]=node[i].y2;
}
sort(y+1,y+1+cnt);
int u=unique(y+1,y+1+cnt)-y-1;
for(register int i=1;i<=n;i++){
node[i].y1=lower_bound(y+1,y+1+u,node[i].y1)-y;
node[i].y2=lower_bound(y+1,y+1+u,node[i].y2)-y;
}
// for(register int i=1;i<=n;i++)
// cout<<node[i].y1<<" "<<node[i].y2<<endl;
cnt=0;
for(register int i=1;i<=n;i++){
a[++cnt].y1=node[i].y1;
a[cnt].y2=node[i].y2;
a[cnt].x=node[i].x1;
a[cnt].k=1;
a[++cnt].y1=node[i].y1;
a[cnt].y2=node[i].y2;
a[cnt].x=node[i].x2;
a[cnt].k=-1;
}
sort(a+1,a+1+cnt,cmp);
for(register int i=1;i<=cnt;i++){
for(register int j=1;j<=u;j++)
if(c[j]) ans+=(a[i].x-a[i-1].x)*(y[j+1]-y[j]);
for(register int j=a[i].y1;j<a[i].y2;j++)
c[j]+=a[i].k;
}
printf("%lld",ans);
return 0;
}