YJJ's Salesman
坑:更新的顺序,x相同的时候用队列缓存
#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define NEG(x) memset(x,0xff,sizeof(x)) #define maxm (1111+10) #define maxn (100000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (1000000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false);cin.tie(0) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") #define fi freopen("C:\\Users\\Administrator\\Desktop\\in","r",stdin) #define fo freopen("C:\\Users\\Administrator\\Desktop\\out","w",stdout) using namespace std; typedef long long ll; typedef unsigned long long ull; struct node { int x,y,v; }a[maxn]; int n; int h[maxn]; ll val[maxn<<3]; ll dp[maxn]; void init() { CLR(val);CLR(dp); } bool cmp(node a,node b) { if(a.x!=b.x)return a.x<b.x; else return a.y<b.y; } void pushup(int rt) { val[rt]=max(val[lson],val[rson]); } void upd(int pos,ll v,int rt,int l,int r) { if(l==r) { val[rt]=max(val[rt],v); return; } int mid=(l+r)>>1; if(pos<=mid)upd(pos,v,lson,l,mid); else upd(pos,v,rson,mid+1,r); pushup(rt); } ll qry(int L,int R,int rt,int l,int r) { if(L<=l&&r<=R)return val[rt]; int mid=l+r>>1; ll res=0; if(L<=mid)res=qry(L,R,lson,l,mid); if(R>mid)res=max(res,qry(L,R,rson,mid+1,r)); return res; } void show(node a) { see(a.x),see(a.y),see(a.v),NL; } queue<int>Q; int main() { acc;int ttt;cin>>ttt;while(ttt--) {init(); cin>>n; for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y>>a[i].v; sort(a+1,a+1+n,cmp); for(int i=1;i<=n;i++)h[i]=a[i].y; sort(h+1,h+n+1); int sz=unique(h+1,h+1+n)-h; //for(int i=1;i<sz;i++)see(i),see(h[i]),NL; for(int i=1;i<=n;i++)a[i].y=lower_bound(h+1,h+sz,a[i].y)-h; ll ans=0; for(int i=1;i<=n;i++) { if(a[i].x!=a[i-1].x) { while(!Q.empty()) { int idx=Q.front();Q.pop(); upd(a[idx].y,dp[idx],1,1,n); } } if(a[i].y-1<1) dp[i]=a[i].v; else dp[i]=qry(1,a[i].y-1,1,1,n)+a[i].v; Q.push(i); ans=max(dp[i],ans); } cout<<ans<<endl; } return 0; } /* 1 3 3 1 1 1 2 2 3 1 3 2 3 1 1 1 1 2 2 3 3 1 3 1 1 1 2 2 2 3 3 3 1 3 1 1 1 1 1 2 3 1 3 */
https://cn.vjudge.net/problem/HDU-6441
Find Integer
构造勾股数,本质上是因数分解+配凑#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define NEG(x) memset(x,0xff,sizeof(x)) #define maxm (1111+10) #define maxn (100000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (1000000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false);cin.tie(0) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") #define fi freopen("C:\\Users\\Administrator\\Desktop\\in","r",stdin) #define fo freopen("C:\\Users\\Administrator\\Desktop\\out","w",stdout) using namespace std; typedef long long ll; typedef unsigned long long ull; int main() {acc; int ttt;cin>>ttt;while(ttt--) { int n,a;cin>>n>>a; if(n==0) cout<<1<<' '<<2<<endl; else if(n==1) cout<<1<<' '<<a+1<<endl; else if(n==2) { if(a%2) { ll y,z,k; k=a>>1; y=2*k*k+2*k; z=y+1; cout<<y<<' '<<z<<endl; } else { ll y,z,k; k=a>>1; y=k*k-1; z=k*k+1; cout<<y<<' '<<z<<endl; } } else cout<<-1<<' '<<-1<<endl; } return 0; }
https://cn.vjudge.net/problem/HDU-6444
Neko's loop
环上最大子段何+分类讨论,细节多
80 Days
也可以用单调队列https://www.cnblogs.com/wangyiming/p/9740435.html用单调区间求每个点为右端点,长度为n的区间的最小值
#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define NEG(x) memset(x,0xff,sizeof(x)) #define maxm (1111+10) #define maxn (1000000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (1000000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false);cin.tie(0) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") #define fi freopen("C:\\Users\\Administrator\\Desktop\\in","r",stdin) #define fo freopen("C:\\Users\\Administrator\\Desktop\\out","w",stdout) using namespace std; typedef long long ll; typedef unsigned long long ull; int n; ll c; ll a[maxn<<1]; deque<ll>Q; int main(){ acc;int ttt;cin>>ttt;while(ttt--) { cin>>n>>c;while(!Q.empty())Q.pop_front(); for(int i=1;i<=n;i++)cin>>a[i]; ll ans=-1LL; for(int i=1;i<=n;i++) { ll t;cin>>t;a[i]-=t;a[i+n]=a[i]; } for(int i=1;i<=n*2;i++) { while(!Q.empty()&&a[i]+c<0) { c-=a[Q.front()]; Q.pop_front(); } if(c+a[i]<0)continue;//如果这个点是起点但不合法就跳过 c+=a[i]; Q.push_back(i); if((int)Q.size()==n) { ans=Q.front();break; } } cout<<ans<<endl; } return 0; }
Tree and Permutation
#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define NEG(x) memset(x,0xff,sizeof(x)) #define maxm (1111+10) #define maxn (1000000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (1000000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false);cin.tie(0) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") #define fi freopen("C:\\Users\\Administrator\\Desktop\\in","r",stdin) #define fo freopen("C:\\Users\\Administrator\\Desktop\\out","w",stdout) using namespace std; typedef long long ll; typedef unsigned long long ull; int n; int head[maxn],tot,to[maxn<<1],pre[maxn<<1],len[maxn<<1],sz[maxn]; ll fac[maxn]; ll ans; void adde(int u,int v,int l) { to[++tot]=v,pre[tot]=head[u],head[u]=tot,len[tot]=l; } void dfs(int u,int fa) { sz[u]=1; for(int i=head[u];i;i=pre[i]) { int v=to[i],l=len[i];if(v==fa)continue; dfs(v,u);sz[u]+=sz[v]; ans=(ans+2LL*l*sz[v]*(n-sz[v]))%mod; } } void init() { fac[0]=1; for(int i=1;i<=100000;i++) {fac[i]=fac[i-1]*1LL*i%mod;} } int main() { acc;init(); while(cin>>n) {CLR(head);tot=0; for(int i=1;i<n;i++) {int u,v,l; cin>>u>>v>>l; adde(u,v,l), adde(v,u,l); } ans=0; dfs(1,0); cout<<ans*fac[n-1]%mod<<endl; } return 0; }
K-Dimensional Foil II
坐标变换变回去的时候不是很懂,但自己写的WA了
#include<bits/stdc++.h>
#define RD1(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d %d",&x,&y)
#define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z)
#define RDL1(x) scanf("%lld",&x)
#define RDL2(x,y) scanf("%lld %lld",&x,&y)
#define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)
#define CLR(x) memset(x,0,sizeof(x))
#define NEG(x) memset(x,0xff,sizeof(x))
#define maxm (1111+10)
#define maxn (500+10)
#define lson (rt<<1)
#define rson (rt<<1|1)
#define mod (1000000007)
#define pi acos(-1)
#define eps 1e-14
#define acc ios::sync_with_stdio(false);cin.tie(0)
#define inf 0x3f3f3f3f
#define INF(x) memset(x,inf,sizeof(x))
#define CLRQ(Q) while(!(Q).empty())(Q).pop()
#define see(x) (cerr<<(#x)<<'='<<(x)<<' ')
#define NL printf("\n")
#define fi freopen("C:\\Users\\Administrator\\Desktop\\in","r",stdin)
#define fo freopen("C:\\Users\\Administrator\\Desktop\\out","w",stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n,k,R,c[maxn],x[maxn],d[maxn];
double chk(double v)
{
double sum=0;
for(int i=1;i<=k;i++)
{
double X=(double)d[i];
if(X>v)sum+=X-v;
}return sum;
}
int main()
{//acc;
int ttt;RD1(ttt);while(ttt--)
{
RD3(n,k,R);for(int i=1;i<=k;i++)RD1(c[i]);
for(int i=1;i<=n;i++)
{
int Sum=0;
for(int j=1;j<=k;j++)
{
RD1(x[j]);d[j]=abs(x[j]-c[j]);
Sum+=d[j];
}
double Ra=(double)R;
double l=0,r=(double)Sum;
while(r-l>1e-9)
{
double mid=(l+r)/2.0;
if(chk(mid)>Ra)l=mid;
else r=mid;
//see(l),see(r),see(Ra),NL;
}
for(int j=1;j<=k;j++)
{
double X=(double)d[j];
double Y;
/*if(X>l)Y=(X-l)*(x[j]<0?-1.0:1.0);
else Y=0;
Y+=(double)c[j];*/
if(X>l)X=l;
if(x[j]>c[j])Y=-X+(double)x[j];
else Y=X+(double)x[j];
printf("%.8f ",Y);
}
printf("\n");
}
}
return 0;
}
Neko's loop
关键点在于,m次的(起点或)终点必定包含最大子段,相当于通过最大子段确定了(起点或)终点,大部分代码里按终点算的
环上子段长度不超过len的最大和可以用单调队列,也可以线段树
m比循环节小,或是一圈的收益<0,吗,这两种单独讨论
#include<bits/stdc++.h> #define RD1(x) scanf("%d",&x) #define RD2(x,y) scanf("%d %d",&x,&y) #define RD3(x,y,z) scanf("%d %d %d",&x,&y,&z) #define RDL1(x) scanf("%lld",&x) #define RDL2(x,y) scanf("%lld %lld",&x,&y) #define RDL3(x,y,z) scanf("%lld %lld %lld",&x,&y,&z) #define CLR(x) memset(x,0,sizeof(x)) #define NEG(x) memset(x,0xff,sizeof(x)) #define maxm (1111+10) #define maxn (10000+10) #define lson (rt<<1) #define rson (rt<<1|1) #define mod (1000000007) #define pi acos(-1) #define eps 1e-14 #define acc ios::sync_with_stdio(false);cin.tie(0) #define inf 0x3f3f3f3f #define INF(x) memset(x,inf,sizeof(x)) #define CLRQ(Q) while(!(Q).empty())(Q).pop() #define see(x) (cerr<<(#x)<<'='<<(x)<<' ') #define NL printf("\n") #define fi freopen("C:\\Users\\Administrator\\Desktop\\in","r",stdin) #define fo freopen("C:\\Users\\Administrator\\Desktop\\out","w",stdout) using namespace std; typedef long long ll; typedef unsigned long long ull; int a[maxn]; bool vis[maxn]; ll sum[maxn<<1]; int n,m,k; ll s; deque<ll>Q; ll cal(int len,int tot) { while(!Q.empty())Q.pop_back(); //see(len),NL; ll ans=0; for(int i=1;i<=tot;i++) { while(!Q.empty()&&i-Q.front()>len)Q.pop_front(); if(Q.empty())ans=max(ans,sum[i]); else ans=max(ans,sum[i]-sum[Q.front()]); while(!Q.empty()&&sum[i]<=sum[Q.back()])Q.pop_back(); Q.push_back(i); } return ans; } int main() { int ks=1; acc;int ttt;cin>>ttt;while(ttt--) { CLR(vis); cin>>n>>s>>m>>k;for(int i=1;i<=n;i++)cin>>a[i]; ll ans=0; for(int ii=1;ii<=n;ii++) { if(vis[ii])continue; int cnt=0; ll val=0; for(int j=ii;!vis[j];j=(j+k-1)%n+1) { vis[j]=1,sum[++cnt]=a[j],val+=1LL*a[j]; //see(j),NL; } for(int i=1;i<=cnt;i++) sum[i+cnt]=sum[i]; for(int i=1;i<=2*cnt;i++) sum[i]+=sum[i-1]; if(m<=cnt) { ans=max(ans,cal(m,cnt*2)); } else if(val<=0) { ans=max(ans,cal(cnt,cnt*2)); } else { //see(ans),see(cal(m%cnt,cnt*2)),see((m/cnt)*val),NL; if(m%cnt) ans=max(ans,cal(m%cnt,cnt*2)+(m/cnt)*val); ans=max(ans,cal(cnt,cnt*2)+(m/cnt-1)*val); //see(ans),NL; } //see(val),see(m),see(cnt),see(k),see(ans),NL; } cout<<"Case #"<<ks++<<": "<<max(s-ans,0LL)<<endl; } return 0; } /* 4 3 10 5 2 3 2 1 5 20 6 3 2 3 2 1 5 3 10 5 2 3 2 1 5 20 6 3 2 3 2 1 5 */