noip模拟37
A. 数列
一个简单的\(exgcd\),
然而我忘了..
A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
#define ll long long int
#define re register ll
#define lf double
#define lbt(x) (x&(-x))
#define lb lower_bound
#define ub upper_bound
#define mp make_pair
#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memcpy(x,y,sizeof x)
inline ll read()
{
ll ss=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
return cit?ss:-ss;
}
} using namespace BSS;
ll n,ans;
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){ x=1,y=0; return a; }
ll d=exgcd(b,a%b,y,x);
y=y-(a/b)*x; return d;
}
signed main(){
ll a,b,x,y,w,t1,t2,d,temp;
n=read(),a=read(),b=read();
d=exgcd(a,b,x,y); a/=d,b/=d;
// cout<<x<<' '<<y<<' '<<d<<endl;
while(n--){
w=abs(read()); temp=1e10;
if(w%d) { puts("-1"); return 0; }
t1=x*w/d,t2=y*w/d; t2+=a*(t1/b),t1-=b*(t1/b);
temp=min(temp,min(abs(t1)+abs(t2),abs(t1+b)+abs(t2-a)));
temp=min(temp,min(abs(t1)+abs(t2),abs(t1-b)+abs(t2+a)));
t1=x*w/d,t2=y*w/d; t1+=b*(t2/a),t2-=a*(t2/a);
temp=min(temp,min(abs(t1)+abs(t2),abs(t1+b)+abs(t2-a)));
temp=min(temp,min(abs(t1)+abs(t2),abs(t1-b)+abs(t2+a)));
ans+=temp;
}
printf("%lld\n",ans);
return 0;
}
B. 数对
类似于曾经做过的一道队长快跑,但是比那道题难度要增加,然而我就是打的队长快跑..
于是挂了..
一道显然的线段树维护Dp.
这道题,我们可以发现和\(a\)、\(b\)都有关.
于是可以按照\(a+b\)排序.
当然按照\(a*b\)排序也可以.
只要和\(a\)、\(b\)都有关即可..
设\(f_{i,j}\)表示前\(i\)个数中,已选的数的\(Max_a\)为\(j\)的最大价值,
然后根据状态转移并线段树维护即可.
B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll long long int
#define ull unsigend ll
#define re register ll
#define lf double
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memset(x,y,sizeof x)
inline ll read() {
ll ss=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
return cit?ss:-ss;
}
} using namespace BSS;
const ll N=1e5+51;
ll n,cnt;
ll lsh[N<<2];
struct I { ll a,b,w,sum; } p[N];
struct II { ll w,lazy; } tr[N<<3];
void spread(ll x){
if(tr[x].lazy){
tr[x<<1].w+=tr[x].lazy;
tr[x<<1|1].w+=tr[x].lazy;
tr[x<<1].lazy+=tr[x].lazy;
tr[x<<1|1].lazy+=tr[x].lazy;
tr[x].lazy=0;
}
return ;
}
void pushup(ll x){
tr[x].w=max(tr[x<<1].w,tr[x<<1|1].w);
return ;
}
ll query(ll x,ll l,ll r,ll ql,ll qr){
if(ql>qr) return 0;
if(l>=ql and r<=qr){
return tr[x].w;
}
spread(x); ll mid=(l+r)>>1;
ll temp=0;
if(ql<=mid) temp=max(temp,query(x<<1,l,mid,ql,qr));
if(qr>=mid+1) temp=max(temp,query(x<<1|1,mid+1,r,ql,qr));
pushup(x);
return temp;
}
void change(ll x,ll l,ll r,ll pos,ll w){
if(l==r){
tr[x].w=max(tr[x].w,w);
return ;
}
spread(x); ll mid=(l+r)>>1;
if(pos<=mid) change(x<<1,l,mid,pos,w);
else change(x<<1|1,mid+1,r,pos,w);
pushup(x); return ;
}
void update(ll x,ll l,ll r,ll ql,ll qr,ll w){
if(ql>qr) return ;
if(l>=ql and r<=qr){
tr[x].w+=w; tr[x].lazy+=w;
return ;
}
spread(x); ll mid=(l+r)>>1;
if(ql<=mid) update(x<<1,l,mid,ql,qr,w);
if(qr>=mid+1) update(x<<1|1,mid+1,r,ql,qr,w);
pushup(x); return ;
}
inline bool comp(I i,I j){ return i.sum<j.sum; }
signed main(){
srand(time(0));
ll t0=clock();
n=read(); ll w;
for(re i=1;i<=n;i++){
lsh[++cnt]=p[i].a=read();
lsh[++cnt]=p[i].b=read();
p[i].sum=p[i].a+p[i].b;
p[i].w=read();
}
sort(p+1,p+1+n,comp); sort(lsh+1,lsh+1+cnt);
cnt=unique(lsh+1,lsh+1+cnt)-lsh-1;
ll res,ans=0;
for(re i=1;i<=n;i++)
{
p[i].a=lb(lsh+1,lsh+1+cnt,p[i].a)-lsh,p[i].b=lb(lsh+1,lsh+1+cnt,p[i].b)-lsh;
// cout<<p[i].a<<' '<<p[i].b<<' '<<p[i].w<<endl;
}
for(re i=1;i<=n;i++){
update(1,1,cnt,p[i].a+1,p[i].b,p[i].w);
res=query(1,1,cnt,1,min(p[i].a,p[i].b));
change(1,1,cnt,p[i].a,res+p[i].w);
}
printf("%lld",tr[1].w);
return 0;
}
C. 最小距离
暴力很好打,但是遍历到的无用情况太多..
维护每个点所和最近的特殊点的最短距离,
并记录是和哪个点的最短距离,
然后枚举每条边,如果两个端点所最靠近的特殊点不一样,那么更新这两个特殊点的答案..
正确性显然.
C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS {
#define ll long long int
#define ull unsigend ll
#define re register ll
#define lf double
#define mp(x,y) make_pair(x,y)
#define lb lower_bound
#define ub upper_bound
#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
#define Fill(x,y) memset(x,y,sizeof x)
#define Copy(x,y) memset(x,y,sizeof x)
inline ll read() {
ll ss=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
return cit?ss:-ss;
}
} using namespace BSS;
const ll N=2e5+51;
ll m,n,s,ts;
ll id[N],head[N],vis[N],dis[N],ans[N],sp[N];
struct I { ll u,v,w,nxt; } e[N<<1];
inline void add(ll u,ll v,ll w){
e[++ts].u=u; e[ts].v=v;
e[ts].w=w; e[ts].nxt=head[u];
head[u]=ts;
}
queue<ll> que;
inline void Spfa(){
for(re i=1;i<=s;i++) que.push(id[i]);
for(re i=1;i<=n;i++) dis[i]=1e11*(!sp[i]);
ll now;
while(que.size()){
now=que.front(); que.pop();
for(re i=head[now];i;i=e[i].nxt){
if(dis[e[i].v]>dis[now]+e[i].w){
dis[e[i].v]=dis[now]+e[i].w;
sp[e[i].v]=sp[now];
if(!vis[e[i].v]) que.push(e[i].v);
vis[e[i].v]=1;
}
}
vis[now]=0;
}
// for(re i=1;i<=n;i++) cout<<dis[i]<<" "<<sp[i]<<'\n';
return ;
}
signed main(){
n=read(); m=read(); s=read();
for(re i=1;i<=s;i++) id[i]=read(),sp[id[i]]=id[i];
ll u,v,w;
for(re i=1;i<=m;i++){
u=read(),v=read(),w=read();
add(u,v,w); add(v,u,w);
}
Spfa();
Fill(ans,0x3f);
for(re i=1;i<=ts;i++){
// cout<<e[i].u<<" "<<e[i].v<<" "<<sp[e[i].u]<<' '<<sp[e[i].v]<<'\n';
if(sp[e[i].u]!=sp[e[i].v]){
ans[sp[e[i].u]]=min(e[i].w+dis[e[i].u]+dis[e[i].v],ans[sp[e[i].u]]);
ans[sp[e[i].v]]=min(e[i].w+dis[e[i].u]+dis[e[i].v],ans[sp[e[i].v]]);
}
}
for(re i=1;i<=s;i++) printf("%lld ",ans[id[i]]);
return 0;
}
D. 真相
考场上以为动态开点能过,于是忘记了优化,
然后\(TLE\)掉了\(35pts\)..
其实这道题的优化应该是挺能想到的..
发现每两个美元符号所对应的点之前的区间(左闭右开)都只和右端点的美元符号是否真实有关,
也就是做每个区间的时候可以看成相互独立.
代码中记录的一些信息可以被替换或删减,码风有点潦草,请自行筛选与改善.
D_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS
{
#define ll long long int
#define re register ll
#define lf double
#define lb lower_bound
#define ub upper_bound
#define mp make_pair
#define File(x,y) freopen(#x,"r",stdin),freopen(#y,"w",stdout)
#define Fill(x,y) memset(x,y,sizeof x);
#define Copy(x,y) memcpy(y,x,sizeof x);
inline ll read()
{
ll ss=0; bool cit=1; char ch;
while(!isdigit(ch=getchar())) if(ch=='-') cit=0;
while(isdigit(ch)) ss=(ss<<3)+(ss<<1)+(ch^48),ch=getchar();
return cit?ss:-ss;
}
} using namespace BSS;
const ll N=1e6+51;
ll m,n,Ts,flag,alls;
ll g[N],tf[N],t[N];
ll pre[3][N],ans[3][N];
map<ll,ll> map1;
vector<ll> vec,v;
inline void Pre(){
for(re i=0;i<=n+1;i++) tf[i]=0,g[i]=0,t[i]=0,pre[1][i]=0,pre[2][i]=0,ans[1][i]=0,ans[2][i]=0;
map1.clear(); vec.clear(); v.clear();
flag=0; alls=0;
}
inline void Init(){
n=read(); char s[5];
for(ll i=1;i<=n;i++){
scanf("%s",s+1);
if(s[1]=='+') g[i]=-2;
else if(s[1]=='-') g[i]=-1;
else g[i]=read(),flag=max(flag,i);
}
return ;
}
inline ll inc(ll i,ll j){ return i+j>n ? i+j-n : i+j; }
inline void Work_None(){
for(re i=0;i<=n+1;i++) tf[i]=0;
for(auto i : v) tf[i]=-1;
for(re i=n;i>=2;i--){
if(g[i-1]>=0) continue;
if((g[i-1]==-1) xor (tf[i]==-1)) tf[i-1]=-1;
else tf[i-1]=1;
}
ll res=0;
for(re i=1;i<=n;i++) res+=(tf[i]==1);
for(auto i : vec){
if(i==res){
puts("inconsistent");
return ;
}
}
puts("consistent");
return ;
}
inline void Work(){
if(flag){
ll res=n-flag;
for(re i=1;i<=n;i++) t[inc(i,res)]=g[i];
for(re i=1;i<=n;i++) g[i]=t[i];
for(ll i=1;i<=n;++i){
if(g[i]>=0){
v.push_back(i);
if(g[i]>n) continue;
if(map1.find(g[i])==map1.end()) vec.push_back(g[i]);
map1[g[i]]=1;
}
}
for(auto i : v){
tf[i]=1; pre[1][i]=1;
for(re j=i;j>=2;j--){
if(g[j-1]>=0) break;
if((g[j-1]==-1) xor (tf[j]==-1)) tf[j-1]=-1;
else pre[1][i]++,tf[j-1]=1;
}
tf[i]=-1;
for(re j=i;j>=2;j--){
if(g[j-1]>=0) break;
if((g[j-1]==-1) xor (tf[j]==-1)) tf[j-1]=-1;
else pre[2][i]++,tf[j-1]=1;
}
}
for(auto j : v){
if(j>n) continue;
ans[1][g[j]]+=pre[1][j];
ans[2][g[j]]+=pre[2][j];
}
for(auto i : vec) alls+=ans[2][i];
for(auto i : vec){
if(i==ans[1][i]+alls-ans[2][i]){
puts("consistent");
return ;
}
}
Work_None();
}
else{
tf[1]=1;
for(re i=1;i<=n-1;i++){
if((tf[i]==-1) xor (g[i]==-1)) tf[i+1]=-1;
else tf[i+1]=1;
}
if(((tf[n]==-1) xor (g[n]==-1))!=tf[1]){
puts("consistent");
return ;
}
tf[1]=-1;
for(re i=1;i<=n-1;i++){
if((tf[i]==-1) xor (g[i]==-1)) tf[i+1]=-1;
else tf[i+1]=1;
}
if(((tf[n]==-1) xor (g[n]==-1)) and (tf[1]==-1)){
puts("consistent");
return ;
}
puts("inconsistent");
return ;
}
return ;
}
signed main(){
Ts=read();
while(Ts--){
Pre();
Init(); Work();
}
return 0;
}