T1 expedition
离散化后记录每一种士兵的出现次数计算即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
LL n,a[100010],b[100010],c[100010];
LL cnt[100010],ans;
int main()
{
freopen("expedition.in","r",stdin);
freopen("expedition.out","w",stdout);
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]),c[i]=b[i];
sort(c+1,c+n+1);
int m=unique(c+1,c+n+1)-c-1;
for(int i=1;i<=n;i++) b[i]=lower_bound(c+1,c+m+1,b[i])-c,cnt[b[i]]+=a[i];
for(int i=1;i<=n;i++) ans+=cnt[b[i]]*cnt[b[i]],cnt[b[i]]=0;
printf("%lld",ans);
return 0;
}
T2 simplify
相当于一个多项式的中缀表达式求值,一个数组其实就可以用来表示一个多项式,数组的每一项是多项式每一项的系数,所以只需要手动模拟一下多项式加法,减法,乘法,递归计算的复杂度 <nobr> O(n4) </nobr>,如果用两个栈分别记录运算的多项式和符号,根据符号的优先级计算,复杂度是 <nobr> O(n3) </nobr>
PS:拉格朗日插值法可以做到 <nobr> O(n2) </nobr>,但实际上和上述算法时间是接近的
//by sdfzchy
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1010,mod=10007;
char s[1010];
int len,optop,top,op[1010];
struct info
{
int len,a[501];
info(){len=0,memset(a,0,sizeof(a));}
void reset(){while(len&&!a[len]) len--;}
}stack[1010];
info operator + (info a,info b)
{
info c;
c.len=max(a.len,b.len);
for(int i=0;i<=c.len;i++) c.a[i]=a.a[i]+b.a[i];
c.reset();
return c;
}
info operator - (info a,info b)
{
info c;
c.len=max(a.len,b.len);
for(int i=0;i<=c.len;i++) c.a[i]=a.a[i]-b.a[i];
c.reset();
return c;
}
info operator * (info a,info b)
{
info c;
c.len=a.len+b.len;
for(int i=0;i<=a.len;i++)
for(int j=0;j<=b.len;j++)
(c.a[i+j]+=a.a[i]*b.a[j])%=mod;
c.reset();
return c;
}
int prio(char a)
{
if(a=='+'||a=='-') return 1;
if(a=='*') return 2;
if(a=='(') return 0;
}
void calc()
{
if(op[optop]=='+') stack[top-1]=stack[top-1]+stack[top];
else if(op[optop]=='-') stack[top-1]=stack[top-1]-stack[top];
else if(op[optop]=='*') stack[top-1]=stack[top-1]*stack[top];
optop--;top--;
}
void pause(){return;}
int main()
{
freopen("simplify.in","r",stdin);
freopen("simplify.out","w",stdout);
scanf("%s",s+1);
len=strlen(s+1);
for(int i=1;i<=len;i++)
{
if(s[i]=='(') op[++optop]='(';
else if(s[i]==')')
{
pause();
while(op[optop]!='(') calc();
optop--;
}
else if(s[i]=='x')
{
info a;
a.a[1]=1;
a.len=1;
memset(stack[top+1].a,0,sizeof(stack[top+1].a));
stack[++top]=a;
}
else if(s[i]>='0'&&s[i]<='9')
{
info a;
int x=0;
while(s[i]>='0'&&s[i]<='9') x=x*10+s[i++]-'0';
i--;
a.a[0]=x;
memset(stack[top+1].a,0,sizeof(stack[top+1].a));
stack[++top]=a;
}
else if(s[i]=='+'||s[i]=='-')
{
if(i==1||(s[i-1]=='('))
{
int flag=(s[i++]=='+')?1:(-1);
if(s[i]=='x')
{
info a;
a.a[1]=flag;
a.len=1;
memset(stack[top+1].a,0,sizeof(stack[top+1].a));
stack[++top]=a;
}
if(s[i]>='0'&&s[i]<='9')
{
info a;
int x=0;
while(s[i]>='0'&&s[i]<='9') x=x*10+s[i++]-'0';
i--;
a.a[0]=x*flag;
memset(stack[top+1].a,0,sizeof(stack[top+1].a));
stack[++top]=a;
}
}
else
{
while(prio(s[i])<=prio(op[optop])) calc();
op[++optop]=s[i];
}
}
else if(s[i]=='*')
{
while(prio(s[i])<=prio(op[optop])) calc();
op[++optop]=s[i];
}
}
while(optop) calc();
cout<<stack[1].len<<endl;
for(int i=0;i<=stack[1].len;i++)
cout<<(stack[1].a[i]%mod+mod)%mod<<endl;
return 0;
}
T3 production
正反向各建一次图跑SPFA即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
const int N=3010;
const int M=100010;
int head[N],ecnt,eecnt,hhead[N],n,m,dis[N],ddis[N],q;
bool vis[N];
struct edge
{
int to,nxt,dis;
}e[M],ee[M];
void add_edge(int u,int v,int w)
{
e[++ecnt].nxt=head[u];
e[ecnt].to=v;
e[ecnt].dis=w;
head[u]=ecnt;
ee[++eecnt].nxt=hhead[v];
ee[eecnt].to=u;
ee[eecnt].dis=w;
hhead[v]=eecnt;
}
void SPFA()
{
int v,u;
queue<int> q;
q.push(1);
dis[1]=0;
vis[1]=1;
while(!q.empty())
{
u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i;i=e[i].nxt)
{
v=e[i].to;
if(dis[u]+e[i].dis<dis[v])
{
dis[v]=dis[u]+e[i].dis;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
}
void SSPFA()
{
int v,u;
queue<int> q;
q.push(1);
ddis[1]=0;
vis[1]=1;
while(!q.empty())
{
u=q.front();
q.pop();
vis[u]=0;
for(int i=hhead[u];i;i=ee[i].nxt)
{
v=ee[i].to;
if(ddis[u]+ee[i].dis<ddis[v])
{
ddis[v]=ddis[u]+ee[i].dis;
if(!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
}
}
int main()
{
freopen("production.in","r",stdin);
freopen("production.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1,u,v,w;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add_edge(u,v,w);
}
memset(dis,0x3f,sizeof(dis));
memset(ddis,0x3f,sizeof(ddis));
SPFA();
SSPFA();
scanf("%d",&q);
// for(int i=1;i<=n;i++) cout<<dis[i]<<" "<<ddis[i]<<endl;
for(int i=1,u,v;i<=q;i++)
{
scanf("%d%d",&u,&v);
int tmp=ddis[u]+dis[v];
if(tmp>=1061109567) printf("-1\n");
else printf("%d\n",tmp);
}
return 0;
}
PS:一套水题…