1022模拟赛
写在前面
今天考了一场51nod
的比赛,感觉很自闭。或许是因为我太菜了
T1小w的铁路图
Idea
题意: 给定一张有向图,对于每一条边,求删去该边后两端点最短路长度。
这题还是比较水的,感觉没啥好说的。图论?
具体看代码吧
Code
namespace Sol{
struct node{
int v,net;
}e[maxn<<1];
int head[maxm],dis[maxm],tot;
int a[maxn],b[maxn];
bool vis[maxm];
queue<int> q;
inline void add(int x,int y){
e[++tot].v=y; e[tot].net=head[x]; head[x]=tot;
}
inline int bfs(int st,int ed){//处理并求解
mem(vis,false);
while(q.size()) q.pop();
q.push(st); dis[st]=0; vis[st]=1;
for(int i=head[st];i;i=e[i].net){//处理边权
int y=e[i].v;
if(y==ed) continue;
q.push(y); dis[y]=1; vis[y]=1;
}
q.pop();
while(q.size()){
int x=q.front(); q.pop();
for(int i=head[x];i;i=e[i].net){
int y=e[i].v;
if(vis[y]) continue;
if(y==ed) return dis[x]+1;
dis[y]=dis[x]+1;
vis[y]=1; q.push(y);
}
}
return -1;
}
inline void Main(){
int n=read(),m=read();
for(int i=1;i<=m;i++){
a[i]=read(); b[i]=read();
add(a[i],b[i]);
}
for(int i=1;i<=m;i++)
printf("%d ",bfs(a[i],b[i]));
}
}
T2矩形的面积交
由于数据过大,这里又开了个题
Idea
这道题看到题目我就想起线段树。。。
因为矩形的面积并就是线段树写的
所以这就是一道 线段树+前缀和?
所以在我看来,这是一道恶心人的题
考场上调出来了,但是只有\(10\ pts\),还不如爆搜的\(20\ pts\)
Code
namespace Sol{
ll ans[maxn];
struct data{
int h,l,r,k,id;//h为高度,l,r为区间,k为系数,id为编号
bool operator<(const data&x)const{return h<x.h;}
}e[maxn<<2];
struct node{
int l,r;
ll add,sum;//表示长度和总和,原谅我不写len,
int s,t;
int lenth(){return r-l+1;}
inline node operator+=(const node x){add+=x.add; sum+=x.sum;}
#define l(x) tree[x].l
#define r(x) tree[x].r
#define s(x) tree[x].s
#define t(x) tree[x].t
#define add(x) tree[x].add
#define sum(x) tree[x].sum//define它不香么?
}tree[maxn<<2];
inline void update(int o){
int lson=o<<1,rson=lson|1;
sum(o)=sum(lson)+sum(rson);
add(o)=add(lson)+add(rson);
}
inline void build(int o,int l,int r){
l(o)=l; r(o)=r;
if(l==r) return;
int lson=o<<1,rson=lson|1;
int mid=l+r>>1;
build(lson,l,mid);
build(rson,mid+1,r);
}
inline void pushdown(int o){
if(s(o)){
int lson=o<<1,rson=lson|1;
s(lson)+=s(o); s(rson)+=s(o);
sum(lson)+=s(o)*tree[lson].lenth();
sum(rson)+=s(o)*tree[rson].lenth();
s(o)=0;
}
if(t(o)){
int lson=o<<1,rson=lson|1;
t(lson)+=t(o); t(rson)+=t(o);//考场上写成了+=s(o).....
add(lson)+=t(o)*tree[lson].lenth();
add(rson)+=t(o)*tree[rson].lenth();
t(o)=0;
}
}
inline void change(int o,int l,int r,int x,int k){
if(l<=l(o)&&r(o)<=r){
s(o)+=x*k; t(o)+=k;
sum(o)+=x*k*tree[o].lenth();
add(o)+=k*tree[o].lenth();
return;
}
pushdown(o);
int lson=o<<1,rson=lson|1;
int mid=l(o)+r(o)>>1;
if(l<=mid) change(lson,l,r,x,k);
if(r> mid) change(rson,l,r,x,k);
update(o);
}
node ask(int o,int l,int r){
if(l<=l(o)&&r(o)<=r) return tree[o];
pushdown(o);
int lson=o<<1,rson=lson|1;
int mid=l(o)+r(o)>>1;
node res=(node){0,0,0,0,0,0};
if(l<=mid) res+=ask(lson,l,r);
if(r> mid) res+=ask(rson,l,r);
return res;
}
inline void Main(){
int n=read(),m=read(),W=read(),L=read(),cnt=0;
for(int i=1;i<=n;i++){
int x=read(),y=read(),a=read(),b=read();
e[++cnt]=(data){x,y+1,b, 1,0};
e[++cnt]=(data){a,y+1,b,-1,0};
}
for(int i=1;i<=m;i++){
int x=read(),y=read(),a=read(),b=read();
e[++cnt]=(data){x,y+1,b,-1,i};
e[++cnt]=(data){a,y+1,b, 1,i};
}
build(1,1,L);
sort(e+1,e+cnt+1);
for(int i=1;i<=cnt;i++){
if(!e[i].id) change(1,e[i].l,e[i].r,e[i].h,e[i].k);
else{
node x=ask(1,e[i].l,e[i].r);
ans[e[i].id]+=e[i].k*(x.add*e[i].h-x.sum);
}
}
for(int i=1;i<=m;i++)
printf("%lld\n",ans[i]);
}
}
T3重排题
Idea
只需要奇数位和偶数位对11 同余。
我们可以预处理\(f[i][j]\)表示\(i\)个数字和模\(11\) 为\(j\)的方案数。
若增加一个数\(x\),有:
\(f[i+1][(j+x)\bmod 11]+=f[i][j]\)
若减去一个数,有:
\(f[i+1][(j+x)\bmod 11]−=f[i][j]\)
现在我们依次填入数字。
对于当前还剩下\(pos\)位,数字和为\(S\) ,我们可以从高到低枚举\(x\),并删除\(x\),如果存在$f[pos][S]>0$0就意味有解;否则加上这个数字,考虑下一个数字。
由于方案数较大,我们需要考虑取模。我这里对988244353
取模。(你找个喜欢的数字就行
Code
namespace Sol{//namespace 真香
int cnt[maxn],f[maxn][20];
int n,sum,Max;
char a[maxn];
inline void add(int x){
for(int i=Max;i>=0;i--)
for(int j=0;j<11;j++)
(f[i+1][(j+x)%11]+=f[i][j])%=mod;
Max++; cnt[x]++;
return;
}
inline void del(int x){
for(int i=0;i<=Max;i++)
for(int j=0;j<11;j++)
(f[i+1][(j+x)%11]+=mod-f[i][j])%=mod;
Max--; cnt[x]--;
return;
}
inline void Main(){
cin>>a+1;
n=strlen(a+1);
f[0][0]=1;
for(int i=1;i<=n;i++){
sum=(sum+a[i]-48)%11;
add(a[i]-48);
}
int half=sum*6%11;
int s0=half,s1=half;
for(int i=1;i<=n;i++){
int S,pos;
if(i&1) pos=n/2-i/2,S=s0;
if(!(i&1)) pos=(n+1)/2-(i+1)/2,S=s1;
int j;
for(j=9;j>=0;j--){
if(cnt[j]==0) continue;
del(j);
if(f[pos][S]) break;
add(j);
}
if(i&1) s1=(s1+11-j)%11;
if(!(i&1)) s0=(s0+11-j)%11;
putchar('0'+j);
}
}
}
\[The \quad End
\]
\[\text{You better know one little thing the only thing;}\\
\text{You're gonna sling is a wedding ring.}\\
\text{《Cause You're My Zing》 - Becky G}
\]
不随波,追随梦;不逐流,攀耸峰。不卑,补我所失;不亢,胜我所向。