8.8模拟赛

T1 lcp

题目大意:

q次询问一个字符串两个后缀的最长公共前缀

思路:

可以二分长度hash判断

 1 #include<iostream>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #define MAXN 100100
11 #define ll long long
12 #define inf 2139062143
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 const int mod1=19260817,mod2=998244353,bas1=137,bas2=233;
22 ll hsh1[MAXN],hsh2[MAXN],pw1[MAXN],pw2[MAXN];
23 int n,ans,a,b;
24 char c[MAXN];
25 int Check(int x)
26 {
27     int va1=(hsh1[a+x-1]-(hsh1[a]*pw1[x-1])%mod1+mod1)%mod1,va2=(hsh2[a+x-1]-(hsh2[a]*pw2[x-1])%mod2+mod2)%mod2;
28     int vb1=(hsh1[b+x-1]-(hsh1[b]*pw1[x-1])%mod1+mod1)%mod1,vb2=(hsh2[b+x-1]-(hsh2[b]*pw2[x-1])%mod2+mod2)%mod2;
29     if(va1==vb1&&va2==vb2) return 1;
30     return 0;
31 }
32 int main()
33 {
34     freopen("lcp.in","r",stdin);
35     freopen("lcp.out","w",stdout);
36     scanf("%s",c+1);n=strlen(c+1);
37     for(int i=pw1[0]=pw2[0]=1;i<=n;i++)
38         pw1[i]=(pw1[i-1]*bas1)%mod1,hsh1[i]=((hsh1[i-1]*bas1)%mod1+c[i]-'a'+1)%mod1,
39         pw2[i]=(pw2[i-1]*bas2)%mod2,hsh2[i]=((hsh2[i-1]*bas2)%mod2+c[i]-'a'+1)%mod2;
40     int q=read(),l,r,mid;
41     while(q--)
42     {
43         a=read(),b=read(),l=ans=1,r=n-max(a,b)+1;
44         if(c[a]!=c[b]) {puts("0");continue;}
45         while(r>=l)
46         {
47             mid=(l+r)>>1;
48             if(Check(mid)) ans=mid,l=mid+1;
49             else r=mid-1;
50         }
51         printf("%d\n",ans);
52     }
53 }
View Code

T2 线段求交

题目大意:

求两个线段的交点 

思路:

使用计算几何

 1 #include<iostream>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #define MAXN 
11 #define ll long long
12 #define inf 2139062143
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,ans;
22 struct Point
23 {
24     double x,y;
25     Point operator - (const Point &a) const
26     {
27         return (Point){x-a.x,y-a.y};
28     }
29     double operator ^ (const Point &a) const
30     {
31         return x*a.y-y*a.x;
32     }
33 };
34 struct Segment{Point st,ed;}g,h;
35 double Area(Point a,Point b,Point c){return (b-a)^(c-a);}
36 bool Intersec(Point a,Point b,Point c,Point d)
37 {
38     if(max(a.x,b.x)<min(c.x,d.x))return false;
39     if(max(a.y,b.y)<min(c.y,d.y))return false;    
40     if(max(c.x,d.x)<min(a.x,b.x))return false;
41     if(max(c.y,d.y)<min(a.y,b.y))return false;
42     if(Area(c,b,a)*Area(b,d,a)<0)return false;
43     if(Area(a,d,c)*Area(d,b,c)<0)return false;
44     return true;
45 }
46 int main()
47 {
48     freopen("intersect.in","r",stdin);
49     freopen("intersect.out","w",stdout);
50     int T=read();
51     while(T--)
52     {
53         n=read(),ans=0;
54         g.st.x=read()*1.0,g.st.y=read()*1.0,g.ed.x=read()*1.0,g.ed.y=read()*1.0;
55         for(int i=1;i<=n;i++)
56         {
57             h.st.x=read()*1.0,h.st.y=read()*1.0,h.ed.x=read()*1.0,h.ed.y=read()*1.0;
58             if(Intersec(g.st,g.ed,h.st,h.ed)){ans=1;continue;}
59         }
60         if(ans) puts("YES");
61         else puts("NO");
62     }
63 }
View Code

T3 spaceship

题目大意:

你在点1处可以带一些油,每条道路有一个额外的权值c,表示当你剩余至少c的油的时候才能走这条路,每条路需要费不同的油

求1到n至少要带多少油

思路:

反跑dij 每次修改dis数组的时候dis[to[i]与max(dis[x]+val[i],limit[i])取min即可

 1 #include<iostream>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<vector>
 9 #include<set>
10 #define MAXN 100100
11 #define ll long long
12 #define inf 2139062143
13 using namespace std;
14 inline int read()
15 {
16     int x=0,f=1;char ch=getchar();
17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
19     return x*f;
20 }
21 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],val[MAXN<<1],lmt[MAXN<<1],cnt;
22 void add(int u,int v,int w,int c){nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w,lmt[cnt]=c;}
23 struct node
24 {
25     int x,dis;
26     bool operator < (const node &a) const
27     {
28         return dis>a.dis;
29     }
30 };
31 int dis[MAXN],vis[MAXN];
32 priority_queue <node> q; 
33 void dij()
34 {
35     memset(dis,127,sizeof(dis));
36     dis[n]=0;q.push((node){n,0});int x,d;
37     while(!q.empty())
38     {
39         x=q.top().x,d=q.top().dis;q.pop();
40         if(vis[x]) continue;
41         vis[x]=1;
42         for(int i=fst[x];i;i=nxt[i])
43             if(dis[to[i]]>max(d+val[i],lmt[i])){dis[to[i]]=max(d+val[i],lmt[i]);q.push((node){to[i],dis[to[i]]});}
44     }
45     if(dis[1]>=inf) puts("-1");
46     else printf("%d",dis[1]);
47 }
48 int main()
49 {
50     freopen("spaceship.in","r",stdin);
51     freopen("spaceship.out","w",stdout);
52     n=read(),m=read();int a,b,c,d;
53     while(m--){a=read(),b=read(),c=read(),d=read();add(a,b,c,d);add(b,a,c,d);}
54     dij();
55 }
View Code

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/9446727.html
8.8