这题2s哇!暴力可水过(x)
题意:
有n个魔法和对应破坏值
如果某个魔法是另一个魔法的后缀且前者破坏值更大
后者可被当做前者的连锁技一起使用
Q个操作
1 :把第x个魔法的破坏值改成y
2 :询问第x个魔法有几个连锁技(包括自己)
暴力暴力暴力!
先判断后缀情况,存储一下可能成为连锁技的魔法
另外存储一个相反的情况,即当前状态改变可能会影响到哪些魔法,并在改变后标记一下被影响的魔法,在之后询问被影响的魔法后再进行更新(虽然感觉没什么大用但应该能节省时间)
#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <cmath>
using namespace std;
const int maxn=1010;
const int INF=0x3f3f3f3f;
const int eps=1e-8;
vector<int>G[maxn],P[maxn];
int len[maxn],sum[maxn],num[maxn],n,m,vis[maxn],s;
char ss[maxn][maxn];
bool flag;
int main()
{
int cases,i,j,k,fg,x,y;
while (~scanf("%d",&cases))
{
int cas=0;
while (cases--)
{
scanf("%d",&n);
for (i=1;i<=n;i++) { scanf("%s%d",ss[i],&num[i]); G[i].clear(); len[i]=strlen(ss[i]); P[i].clear(); P[i].push_back(i); }
for (i=1;i<=n;i++)
{
sum[i]=0;
for(j=1;j<=n;j++)
if (i!=j && len[i]<=len[j])
{
flag=true;
for (k=1;k<=len[i];k++)
if (ss[i][len[i]-k]!=ss[j][len[j]-k]) {flag=false; break;}
if (flag) { G[i].push_back(j); P[j].push_back(i); if (num[i]>=num[j]) sum[i]++; }
}
}
memset(vis,0,sizeof(vis));
scanf("%d",&m);
while (m--)
{
scanf("%d",&fg);
if (fg==2)
{
scanf("%d",&x);
if (!vis[x]) printf("%d\n",sum[x]+1);
else
{
s=0;
for (i=0;i<G[x].size();i++)
if (num[x]>=num[G[x][i]]) s++;
printf("%d\n",s+1);
sum[x]=s;
vis[x]=0;
}
}
else
{
scanf("%d%d",&x,&y); num[x]=y;
for (i=0;i<P[x].size();i++) vis[P[x][i]]=1;
}
}
}
}
return 0;
}