你说我怎么这么菜呢?
请看我直播把260分扔成120分......
T1:
题目就是给你个trie,在trie的每个节点上存在一些点,我们要询问这些点中权值最大的一些。
炸胡题,我们直接在节点上开vector把那些点都push进去就好了......
这不像后缀自动机会卡n^2,这个东西由于有输入数据长度限制所以不会。
于是我写了线段树。虽然不好写吧,但是也不应该爆零啊。
注意输出描述的最后一句,行末不应有空格。也就是说,这题卡行末空格!于是我就华丽爆零了。
(自己不看题还能怪谁?)
考场爆零代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #define debug cout 7 using namespace std; 8 const int maxn=1e5+1e2,maxe=1e7+1e2; 9 10 int n; 11 struct Node { 12 int val,id; 13 vector<char*> ss; 14 friend bool operator < (const Node &a,const Node &b) { 15 return a.val > b.val; 16 } 17 }ns[maxn]; 18 19 struct SegmentTree { 20 int lson[maxe],rson[maxe],siz[maxe],cnt; 21 inline void insert(int &pos,int l,int r,int tar) { 22 if( !pos ) pos = ++cnt; ++siz[pos]; 23 if( l == r ) return; 24 const int mid = ( l + r ) >> 1; 25 if( tar <= mid ) insert(lson[pos],l,mid,tar); 26 else insert(rson[pos],mid+1,r,tar); 27 } 28 inline int find(int pos,int l,int r,int tar) { 29 if( !pos ) return 0; 30 if( l == r) return 1; 31 const int mid = ( l + r ) >> 1; 32 if( tar <= mid ) return find(lson[pos],l,mid,tar); 33 return find(rson[pos],mid+1,r,tar); 34 } 35 inline int query(int pos,int l,int r,const int &ll,const int &rr) { 36 if( !pos ) return 0; 37 if( ll <= l && r <= rr ) return siz[pos]; 38 const int mid = ( l + r ) >> 1; 39 if( rr <= mid ) return query(lson[pos],l,mid,ll,rr); 40 else if( ll > mid ) return query(rson[pos],mid+1,r,ll,rr); 41 return query(lson[pos],l,mid,ll,rr) + query(rson[pos],mid+1,r,ll,rr); 42 } 43 inline int kth(int pos,int l,int r,int k) { // assert it have kth . 44 if( l == r ) return l; 45 const int mid = ( l + r ) >> 1; 46 if( k <= siz[lson[pos]] ) return kth(lson[pos],l,mid,k); 47 else return kth(rson[pos],mid+1,r,k-siz[lson[pos]]); 48 } 49 inline void dfs(int pos,int l,int r,const int &ll,const int &rr) { 50 if( !pos ) return; 51 if( l == r ) return void(printf("%d ",ns[l].id)); 52 const int mid = ( l + r ) >> 1; 53 if( rr <= mid ) dfs(lson[pos],l,mid,ll,rr); 54 else if( ll > mid ) dfs(rson[pos],mid+1,r,ll,rr); 55 else dfs(lson[pos],l,mid,ll,rr) , dfs(rson[pos],mid+1,r,ll,rr); 56 } 57 }cmt; 58 59 struct Trie { 60 int ch[maxn][26],roots[maxn],fa[maxn],root,cnt; 61 Trie() { root = cnt = 1; } 62 inline void insert(char* s,int li,int id) { 63 int now = root; 64 //cerr<<"s = "<<s<<endl; 65 for(int i=0;i<li;i++) { // starts from 0 ! 66 const int t = s[i] - 'a'; 67 if( !ch[now][t] ) ch[now][t] = ++cnt; 68 now = ch[now][t]; 69 if( !cmt.find(roots[now],1,n,id) ) 70 cmt.insert(roots[now],1,n,id); 71 } 72 } 73 inline void query(char* s,int li,int t) { 74 int now = root; 75 for(int i=1;i<=li;i++) { // starts from 1 ! 76 const int t = s[i] - 'a'; 77 now = ch[now][t]; 78 } 79 if( !now ) return void(puts("0")); 80 int tot = cmt.query(roots[now],1,n,1,n); 81 printf("%d ",tot); 82 if( tot <= t ) cmt.dfs(roots[now],1,n,1,n); 83 else { 84 int kth = cmt.kth(roots[now],1,n,t); 85 cmt.dfs(roots[now],1,n,1,kth); 86 } 87 putchar('\n'); 88 } 89 }trie; 90 91 inline void pushstr(int id) { 92 static char s[maxn]; 93 scanf("%s",s); 94 int len = strlen(s); 95 char* t = new char[len+1]; 96 memcpy(t,s,sizeof(char)*(len+1)); 97 ns[id].ss.push_back(t); 98 } 99 100 int main() { 101 static int m; 102 static char in[maxn]; 103 scanf("%d%d",&n,&m); 104 for(int i=1,t;i<=n;i++) { 105 scanf("%d%d",&ns[i].val,&t) , ns[i].id = i - 1; 106 while(t--) pushstr(i); 107 } 108 sort(ns+1,ns+1+n); 109 for(int i=1;i<=n;i++) 110 for(unsigned j=0;j<ns[i].ss.size();j++) { 111 trie.insert(ns[i].ss[j],strlen(ns[i].ss[j]),i); 112 } 113 for(int i=1,t,li;i<=m;i++) { 114 scanf("%d%s",&t,in+1) , li = strlen(in+1); 115 trie.query(in,li,t); 116 } 117 return 0; 118 }