……三道大水题……
三道题都写了……然而40’…………看来是要GG QAQ
天天崩的我已经……无所畏惧QwQ
T1
关于x的多项式求导,就是个大模拟题…………我数组开小了
然后……嗯……
特判puts("0")的时候……顺手在main里面return puts("0");了……嗯……人造的RE0,稳得不行
#include<bits/stdc++.h>
#define MAXN 100005
using namespace std; int n;
char s[MAXN];
char put[205][50];
int fu[205];
int main(){
freopen("equation.in","r",stdin);
freopen("equation.out","w",stdout);
scanf("%s",s),n=strlen(s);
long long xi=0,zhi=0;
int cnt=0;
int up_flag=0;
int fu_flag=0;
for(int i=0;i<n;++i){
char cur=s[i];
if(cur=='x'){
zhi=1;
if(!xi) xi=1;
}
if(cur=='^'){
up_flag=1,zhi=0;
}
if(isdigit(cur)){
if(up_flag) zhi=zhi*10+cur-'0';
else xi=xi*10+cur-'0';
}
if(cur=='+'||i==n-1){
if(zhi){
fu[++cnt]=fu_flag? -1:1;
if(zhi>1){
if(zhi==2) sprintf(put[cnt],"%lldx",xi*zhi);
else sprintf(put[cnt],"%lldx^%lld",xi*zhi,zhi-1);
}
else sprintf(put[cnt],"%lld",xi*zhi);
}
xi=0,zhi=0,up_flag=0,fu_flag=0;
}
if(cur=='-'||i==n-1){
if(zhi){
fu[++cnt]=fu_flag? -1:1;
if(zhi>1){
if(zhi==2) sprintf(put[cnt],"%lldx",xi*zhi);
else sprintf(put[cnt],"%lldx^%lld",xi*zhi,zhi-1);
}
else sprintf(put[cnt],"%lld",xi*zhi);
}
xi=0,zhi=0,up_flag=0,fu_flag=1;
}
}
if(!cnt) return puts("0"),0;
for(int i=1;i<=cnt;++i){
if(i==1){
if(fu[i]==-1) printf("-%s",put[i]);
else printf("%s",put[i]);
}
else
putchar(fu[i]==-1?'-':'+'),printf("%s",put[i]);
}
return 0;
}
T2
给一个数列,选取一个区间,使区间里数i的数量在(Li与Ri之间(闭区间
解一:naive地暴力……枚举左右端点,check是否合法 O(n*n*k)
解二:枚举左右端点,因为左右端点的移动只影响一个值是否合法 check可以优化成O(1) 于是O(n*n)
解三:枚举左端点,右端点随着左端点右移只会往右移动,于是是个O(n)的做法
解四:听说可以nlogn地乱搞
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define MAXN 200005
#define INF 0x3f3f3f3f
using namespace std; int n,k;
int a[MAXN];
int Min[MAXN],Max[MAXN];
int cnt1[MAXN],cnt2[MAXN];
int l,r;
int main(){
freopen("survey.in","r",stdin);
freopen("survey.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i) scanf("%d",a+i),++cnt1[a[i]];
for(int i=1;i<=k;++i) scanf("%d%d",Min+i,Max+i);
Min[0]=0,Max[0]=INF;
for(int i=1;i<=k;++i)
if(cnt1[i]<Min[i]) return puts("0"),0;
for(int i=n;i;--i){
--cnt1[a[i]];
if(cnt1[a[i]]<Min[a[i]]){
l=i,++cnt1[a[l]];
break;
}
}
cnt1[0]=cnt2[0]=1;
long long ans=0;
for(int i=1;i<=n;++i){
--cnt1[a[i-1]],--cnt2[a[i-1]];
while(l<n && cnt1[a[i-1]]<Min[a[i-1]]) ++cnt1[a[++l]];
if(cnt1[a[i-1]]<Min[a[i-1]]) break;
while(r<n && cnt2[a[r+1]]<Max[a[r+1]]) ++cnt2[a[++r]];
printf("i = %d l = %d r = %d\n",i,l,r);
ans+=max(0,r-l+1);
}
printf("%lld",ans);
return 0;
}
T3
一棵树上有三个点s,p,q三个人分别从s,p,q三个点出发,对于每个三秒,在第一秒时s会走一步,第二秒p和q会向s所在的方向走一步,第三秒和第二秒相同
问pq与s相遇的最晚时间中,更早的那个是多久
思路:因为是棵树,所以s肯定不会走到p或q的后面去,所以可以理解成染色,s不能染pq,pq随便染,最后一个被pq染掉的且被s染过的节点就是答案
所以模拟一下bfs就好
然而因为懒得多写几个bfs直接开模拟,于是很多细节没有考虑到,debug了好久啊QwQ
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#define MAXN 200005
#define INF 0x3f3f3f3f
using namespace std; int n,p0,p1,p2;
struct t1{
int to,nxt;
}edge[MAXN<<1]; int cnt_edge=0;
int fst[MAXN];
void addedge(int x,int y){
edge[++cnt_edge].to=y;
edge[cnt_edge].nxt=fst[x];
fst[x]=cnt_edge;
edge[++cnt_edge].to=x;
edge[cnt_edge].nxt=fst[y];
fst[y]=cnt_edge;
}
int col[MAXN],tim[MAXN];
int tag[MAXN];
const int MN3=MAXN*3;
int que[MN3],head,tail;
int in_que[MAXN];
int skp[MN3];
queue<int> q2;
int ans=0;
void bfs(){
head=tail=0;
que[tail++]=p0,que[tail++]=p1,que[tail++]=p2;
memset(tim,INF,sizeof tim);
memset(in_que,-1,sizeof in_que);
tim[p1]=tim[p2]=0;
int now;
while(head^tail){
if(skp[head]){
++head;
continue;
}
now=que[head++];
// printf("now = %d\n",now);
if(head==MN3) head=0;
if(col[now]==1){
for(int tmp=fst[now];tmp;tmp=edge[tmp].nxt){
int aim=edge[tmp].to;
if(col[aim]) continue;
col[aim]=1;
que[tail++]=aim;
in_que[aim]=tail-1;
if(tail==MN3) tail=0;
}
}
else{
while(!q2.empty()) q2.pop();
for(int tmp=fst[now];tmp;tmp=edge[tmp].nxt){
int aim=edge[tmp].to;
if(col[aim]==1) tag[aim]=1;
if(col[aim]!=2){
if(~in_que[aim]) skp[in_que[aim]]=1;
q2.push(aim);
tim[aim]=tim[now]+2;
col[aim]=2;
}
else
if(tim[now]+2<tim[aim])
tim[aim]=tim[now]+2,q2.push(aim);
}
while(!q2.empty()){
now=q2.front();
q2.pop();
for(int tmp=fst[now];tmp;tmp=edge[tmp].nxt){
int aim=edge[tmp].to;
if(col[aim]==1) tag[aim]=1;
if(col[aim]!=2){
que[tail++]=aim;
if(~in_que[aim])
skp[in_que[aim]]=1;
if(tail==MN3) tail=0;
tim[aim]=tim[now]+1;
col[aim]=2;
}
else
if(tim[now]+2<tim[aim])
tim[aim]=tim[now]+1,que[tail++]=aim;
}
}
}
}
}
int read_x,read_y;
int main(){
freopen("track.in","r",stdin);
// freopen("track.out","w",stdout);
scanf("%d%d%d%d",&n,&p0,&p1,&p2);
if(p0==p1||p0==p2) return puts("0"),0;
for(int i=1;i<n;++i)
scanf("%d%d",&read_x,&read_y),addedge(read_x,read_y);
col[p1]=col[p2]=2;
col[p0]=1;
bfs();
// for(int i=1;i<=n;++i) printf(" %d tag = %d tim = %d\n",i,tag[i],tim[i]);
for(int i=1;i<=n;++i) if(tag[i]) ans=max(ans,tim[i]);
printf("%d",ans);
return 0;
}