一句话题解集合。
1061: [Noi2008]志愿者招募
单纯形,运用对偶原理转化过来,变成标准形然后单纯性裸上即可。
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstring> 5 #include<algorithm> 6 const double eps=1e-6; 7 const double oo =1e9; 8 double a[10001][1001]; 9 double b[10001]; 10 double c[1001]; 11 int n,m; 12 int read(void) 13 { 14 int ans=0; 15 int f=1; 16 char ch=getchar(); 17 while(ch<'0'||ch>'9') 18 { 19 if(ch=='-')f=-f; 20 ch=getchar(); 21 } 22 while(ch<='9'&&ch>='0') 23 { 24 ans=ans*10+ch-'0'; 25 ch=getchar(); 26 } 27 return ans*f; 28 } 29 void pivot(double&ans,int l,int e) 30 { 31 b[l]/=a[l][e]; 32 for(int i=1;i<=n;i++)if(i!=e)a[l][i]/=a[l][e]; 33 a[l][e]=1.00/a[l][e]; 34 for(int i=1;i<=m;i++) 35 if(fabs(a[i][e])>eps&&i!=l) 36 { 37 b[i]-=b[l]*a[i][e]; 38 for(int j=1;j<=n;j++)if(j!=e) 39 a[i][j]-=a[i][e]*a[l][j]; 40 a[i][e]=-a[i][e]*a[l][e]; 41 } 42 ans+=c[e]*b[l]; 43 for(int i=1;i<=n;i++)if(i!=e)c[i]-=c[e]*a[l][i]; 44 c[e]=-c[e]*a[l][e]; 45 return ; 46 } 47 double simplex(void) 48 { 49 double ans=0; 50 while(true) 51 { 52 int e,l; 53 for(e=1;e<=n;e++)if(c[e]>eps)break; 54 if(e>n)return ans; 55 double mins=oo; 56 for(int i=1;i<=m;i++) 57 if(a[i][e]>eps&&mins>b[i]/a[i][e]) 58 mins=b[i]/a[i][e],l=i; 59 if(mins>=oo-eps)return oo; 60 pivot(ans,l,e); 61 } 62 return ans; 63 } 64 int main() 65 { 66 // freopen("a.in","r",stdin); 67 scanf("%d%d",&n,&m); 68 for(int i=1;i<=n;i++)c[i]=read(); 69 for(int i=1;i<=m;i++) 70 { 71 int s,t; 72 scanf("%d%d",&s,&t); 73 for(int j=s;j<=t;j++) 74 { 75 if(j<1)j=1;if(j>n)break; 76 a[i][j]=1; 77 } 78 b[i]=read(); 79 } 80 printf("%d ",(int)(simplex()+0.5)); 81 return 0; 82 }
1197: [HNOI2006]花仙子的魔法
神TM递推题,考虑升维的计算仍然是类似的,就有递推式$f_{[i][j]}=f_{[i-1][j-1]}+f_{[i][j-1]}$
#include<cstdio> typedef long long lnt; lnt dp[17][1000]; int n,m; int main() { // freopen("flower.in","r",stdin); // freopen("flower.out","w",stdout); scanf("%d%d",&m,&n);dp[1][0]=1; for(int i=1;i<=m;i++)dp[1][i]=i*2; for(int i=2;i<=n;i++) { dp[i][0]=1; for(int j=1;j<=m;j++)dp[i][j]=dp[i][j-1]+dp[i-1][j-1]; } printf("%lld ",dp[n][m]); return 0; }
2161: 布娃娃
偏不写扫描线,考虑对于同一种p,询问编号越小越先得到答案,先离散化按p排序建立线段树,询问挂在叶节点上,维护区间最小询问。
按照c从大到小的顺序加入查询,区间-1,若最小值变成0,则说明这个区间是某个p的答案,二分删除这个询问。
易知每个询问最多被删除一次,所以时间复杂度仍为$O(nlog_2n)$
1 #include<map> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<algorithm> 6 #define Mod 19921228 7 #define lll spc<<1 8 #define rrr spc<<1|1 9 typedef long long lnt; 10 struct data{ 11 lnt add; 12 lnt first; 13 lnt mod; 14 lnt prod; 15 void Insert(void) 16 { 17 scanf("%lld%lld%lld%lld",&add,&first,&mod,&prod); 18 return ; 19 } 20 lnt sta(void) 21 { 22 return first%mod; 23 } 24 lnt S(lnt lst,lnt i) 25 { 26 return (prod*lst+add+i)%mod; 27 } 28 }P,C,L,R; 29 struct pnt{ 30 int p; 31 int l,r; 32 int no; 33 int c; 34 void sta(void) 35 { 36 no=1; 37 p=P.sta(); 38 l=L.sta(); 39 r=R.sta(); 40 c=C.sta(); 41 return ; 42 } 43 void ch(void) 44 { 45 if(l>r)std::swap(l,r); 46 return ; 47 } 48 }p[100001]; 49 struct trnt{ 50 int minval; 51 int to; 52 int h; 53 int lzt; 54 }tr[1300000]; 55 int cnt; 56 int tot; 57 lnt ans; 58 int n; 59 int a[300001]; 60 std::map<int,int>M; 61 std::vector<int>v[300001]; 62 bool cmp(pnt x,pnt y) 63 { 64 return x.c>y.c; 65 } 66 void pushup(int spc) 67 { 68 tr[spc].minval=std::min(tr[lll].minval,tr[rrr].minval); 69 return ; 70 } 71 void add(int spc,int v) 72 { 73 tr[spc].minval+=v; 74 tr[spc].lzt+=v; 75 return ; 76 } 77 void pushdown(int spc) 78 { 79 if(tr[spc].lzt) 80 { 81 add(lll,tr[spc].lzt); 82 add(rrr,tr[spc].lzt); 83 if(!tr[spc].to)tr[spc].lzt=0; 84 } 85 return ; 86 } 87 void build(int l,int r,int spc) 88 { 89 if(l==r) 90 { 91 tr[spc].h=0; 92 tr[spc].to=l; 93 if(v[l].size())tr[spc].minval=v[l][0]; 94 else tr[spc].minval=0x3f3f3f3f; 95 return ; 96 } 97 int mid=(l+r)>>1; 98 build(l,mid,lll); 99 build(mid+1,r,rrr); 100 pushup(spc); 101 return ; 102 } 103 void update(int l,int r,int ll,int rr,int spc) 104 { 105 if(l>rr||ll>r)return ; 106 if(ll<=l&&r<=rr) 107 { 108 add(spc,-1); 109 return ; 110 } 111 pushdown(spc); 112 int mid=(l+r)>>1; 113 update(l,mid,ll,rr,lll); 114 update(mid+1,r,ll,rr,rrr); 115 pushup(spc); 116 return ; 117 } 118 void check(int spc,int V) 119 { 120 if(tr[spc].minval>0)return ; 121 if(tr[spc].to) 122 { 123 ans=(ans+V)%Mod; 124 tr[spc].h++; 125 int i=tr[spc].to; 126 if(tr[spc].h>=v[i].size())tr[spc].minval=0x3f3f3f3f; 127 else{ 128 tr[spc].minval=v[i][tr[spc].h]+tr[spc].lzt; 129 } 130 return ; 131 } 132 pushdown(spc); 133 check(lll,V); 134 check(rrr,V); 135 pushup(spc); 136 return ; 137 } 138 int main() 139 { 140 scanf("%d",&n); 141 P.Insert(),C.Insert(),L.Insert(),R.Insert(); 142 p[1].sta(); 143 for(int i=2;i<=n;i++) 144 { 145 p[i].no=i; 146 p[i].p=P.S(p[i-1].p,i); 147 p[i].l=L.S(p[i-1].l,i); 148 p[i].r=R.S(p[i-1].r,i); 149 p[i].c=C.S(p[i-1].c,i); 150 a[++cnt]=p[i].l; 151 a[++cnt]=p[i].r; 152 a[++cnt]=p[i].p; 153 } 154 a[++cnt]=p[1].l; 155 a[++cnt]=p[1].r; 156 a[++cnt]=p[1].p; 157 std::sort(a+1,a+cnt+1);a[0]=-1; 158 for(int i=1;i<=cnt;i++) 159 { 160 if(M.find(a[i])==M.end())M[a[i]]=++tot; 161 } 162 for(int i=1;i<=n;i++) 163 { 164 p[i].l=M[p[i].l]; 165 p[i].r=M[p[i].r]; 166 p[i].p=M[p[i].p]; 167 v[p[i].p].push_back(i); 168 } 169 for(int i=1;i<=n;i++)p[i].ch(); 170 build(1,tot,1); 171 std::sort(p+1,p+n+1,cmp); 172 for(int i=1;i<=n;i++) 173 { 174 update(1,tot,p[i].l,p[i].r,1); 175 check(1,p[i].c); 176 } 177 printf("%lld ",(ans%Mod+Mod)%Mod); 178 return 0; 179 }