BZOJ1500 [NOI2005]维修数列(Splay tree)

[Submit][Status][Discuss]

Description

请写一个程序,要求维护一个数列,支持以下 6 种操作:
请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格

Input

输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

Output

对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

Sample Input

9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUM

Sample Output

-1
10
1
10

HINT

 

题解:Splay tree模板题;
自己的板子:
  1 #include<bits/stdc++.h>
  2 #define RI register int
  3 #define For(i,a,b) for (RI i=a;i<=b;++i)
  4 using namespace std;
  5 const int inf=0x3f3f3f3f;
  6 const int N=1e6+17;
  7 int n,m,rt,cnt;
  8 int a[N],id[N],fa[N],c[N][2];
  9 int sum[N],sz[N],v[N],mx[N],lx[N],rx[N];
 10 bool tag[N],rev[N];
 11 //tag表示是否有统一修改的标记,rev表示是否有统一翻转的标记
 12 //sum表示这个点的子树中的权值和,v表示这个点的权值
 13 //lx[]是一个子树以最左端为起点向右延伸的最大子串和,rx类似 
 14 //mx[]是当前子树的最大子串和
 15 queue<int> q;
 16 inline int read()
 17 {
 18     RI x=0,f=1;char ch=getchar();
 19     while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
 20     while('0'<=ch&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
 21     return x*f;
 22 }
 23 inline void pushup(RI x)
 24 {
 25     RI l=c[x][0],r=c[x][1];
 26     sum[x]=sum[l]+sum[r]+v[x];
 27     sz[x]=sz[l]+sz[r]+1;
 28     mx[x]=max(mx[l],max(mx[r],rx[l]+v[x]+lx[r]));
 29     lx[x]=max(lx[l],sum[l]+v[x]+lx[r]);
 30     rx[x]=max(rx[r],sum[r]+v[x]+rx[l]);
 31 }
 32 //上传记录标记
 33 inline void pushdown(RI x)
 34 {
 35     RI l=c[x][0],r=c[x][1];
 36     if(tag[x])
 37     {
 38         rev[x]=tag[x]=0;//我们有了一个统一修改的标记,再翻转就没有什么意义了
 39         if(l) tag[l]=1,v[l]=v[x],sum[l]=v[x]*sz[l];
 40         if(r) tag[r]=1,v[r]=v[x],sum[r]=v[x]*sz[r];
 41         if(v[x]>=0) 
 42         {
 43             if(l) lx[l]=rx[l]=mx[l]=sum[l];
 44             if(r) lx[r]=rx[r]=mx[r]=sum[r];
 45         }
 46         else
 47         {
 48             if(l) lx[l]=rx[l]=0,mx[l]=v[x];
 49             if(r) lx[r]=rx[r]=0,mx[r]=v[x];
 50         }
 51     }
 52     if(rev[x])
 53     {
 54         rev[x]=0;rev[l]^=1;rev[r]^=1;
 55         swap(lx[l],rx[l]);swap(lx[r],rx[r]);
 56         //注意,在翻转操作中,前后缀的最大和子序列都反过来了 
 57         swap(c[l][0],c[l][1]);swap(c[r][0],c[r][1]);
 58     }
 59 }
 60 inline void rotate(RI x,RI &k)
 61 {
 62     RI y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1;
 63     if (y==k)k=x;else c[z][c[z][1]==y]=x;
 64     fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
 65     c[y][l]=c[x][r];c[x][r]=y;
 66     pushup(y);pushup(x);
 67     //旋转操作,一定要上传标记且顺序不能变 
 68 }
 69 inline void splay(RI x,RI &k)
 70 {
 71     while(x!=k)
 72     {
 73         int y=fa[x],z=fa[y];
 74         if(y!=k)
 75         {
 76             if((c[z][0]==y)^(c[y][0]==x)) rotate(x,k);
 77             else rotate(y,k);
 78         }
 79         rotate(x,k);
 80     }
 81 }
 82 //这是整个程序的核心之一,毕竟是伸展操作嘛
 83 inline int find(RI x,RI rk)
 84 {//返回当前序列第rk个数的标号 
 85     pushdown(x);
 86     RI l=c[x][0],r=c[x][1];
 87     if(sz[l]+1==rk) return x;
 88     if(sz[l]>=rk) return find(l,rk);
 89     else return find(r,rk-sz[l]-1);
 90 }
 91 inline void recycle(RI x)
 92 {//这就是用时间换空间的回收冗余编号机制,很好理解
 93     RI &l=c[x][0],&r=c[x][1];
 94     if(l) recycle(l);
 95     if(r) recycle(r);
 96     q.push(x);
 97     fa[x]=l=r=tag[x]=rev[x]=0;
 98 }
 99 inline int split(RI k,RI tot)//找到[k+1,k+tot]
100 {
101     RI x=find(rt,k),y=find(rt,k+tot+1);
102     splay(x,rt);splay(y,c[x][1]);
103     return c[y][0];
104 }
105 //这个split操作是整个程序的核心之三
106 //我们通过这个split操作,找到[k+1,k+tot],并把k,和k+tot+1移到根和右儿子的位置
107 //然后我们返回了这个右儿子的左儿子,这就是我们需要操作的区间
108 inline void query(RI k,RI tot)
109 {
110     RI x=split(k,tot);
111     printf("%d\n",sum[x]);
112 }
113 inline void modify(RI k,RI tot,RI val)//MAKE-SAME
114 {
115     RI x=split(k,tot),y=fa[x];
116     v[x]=val;tag[x]=1;sum[x]=sz[x]*val;
117     if(val>=0) lx[x]=rx[x]=mx[x]=sum[x];
118         else lx[x]=rx[x]=0,mx[x]=val;
119     pushup(y);pushup(fa[y]);
120     //每一步的修改操作,由于父子关系发生改变
121     //及记录标记发生改变,我们需要及时上传记录标记
122 }
123 inline void rever(RI k,RI tot)//翻转 
124 {
125     RI x=split(k,tot),y=fa[x];
126     if(!tag[x])
127     {
128         rev[x]^=1;
129         swap(c[x][0],c[x][1]);
130         swap(lx[x],rx[x]);
131         pushup(y);pushup(fa[y]);
132     }
133     //同上
134 }
135 inline void erase(RI k,RI tot)//DELETE
136 {
137     RI x=split(k,tot),y=fa[x];
138     recycle(x);c[y][0]=0;
139     pushup(y);pushup(fa[y]);
140     //同上
141 }
142 inline void build(RI l,RI r,RI f)
143 {
144     RI mid=(l+r)>>1,now=id[mid],pre=id[f];
145     if(l==r)
146     {
147         mx[now]=sum[now]=a[l];
148         tag[now]=rev[now]=0;
149         //这里这个tag和rev的清0是必要,因为这个编号可能是之前冗余了
150         lx[now]=rx[now]=max(a[l],0);
151         sz[now]=1;
152     }
153     if(l<mid) build(l,mid-1,mid);
154     if(mid<r) build(mid+1,r,mid);
155     v[now]=a[mid]; fa[now]=pre;
156     pushup(now); //上传记录标记
157     c[pre][mid>=f]=now;
158     //当mid>=f时,now是插入到又区间取了,所以c[pre][1]=now,当mid<f时同理
159 }
160 inline void insert(RI k,RI tot)
161 {
162     for(int i=1;i<=tot;++i) a[i]=read();
163     for(int i=1;i<=tot;++i)
164     {
165         if(!q.empty()) id[i]=q.front(),q.pop();
166         else id[i]=++cnt;//利用队列中记录的冗余节点编号
167     }
168     build(1,tot,0);
169     RI z=id[(1+tot)>>1];
170     RI x=find(rt,k+1),y=find(rt,k+2);
171      //首先,依据中序遍历,找到我们需要操作的区间的实际编号
172     splay(x,rt);splay(y,c[x][1]);
173     //把k+1(注意我们已经右移了一个单位)和(k+1)+1移到根和右儿子
174     fa[z]=y;c[y][0]=z;
175     //直接把需要插入的这个平衡树挂到右儿子的左儿子上去就好了
176     pushup(y);pushup(x);
177     //上传记录标记
178 }
179 //可以这么记,只要用了split就要重新上传标记
180 //只有find中需要下传标记
181 int main()
182 {
183     n=read(),m=read();
184     mx[0]=a[1]=a[n+2]=-inf;
185     For(i,1,n) a[i+1]=read();
186     For(i,1,n+2) id[i]=i;//虚拟了两个节点1和n+2,然后把需要操作区间整体右移一个单位
187     build(1,n+2,0);//建树
188     rt=(n+3)>>1;cnt=n+2;//取最中间的为根
189     RI k,tot,val;char ch[10];
190     while(m--)
191     {
192         scanf("%s",ch);
193         if(ch[0]!='M' || ch[2]!='X') k=read(),tot=read();
194         if(ch[0]=='I') insert(k,tot);
195         if(ch[0]=='D') erase(k,tot);//DELETE
196         if(ch[0]=='M')
197         {
198             if(ch[2]=='X') printf("%d\n",mx[rt]);//MAX-SUM
199             else val=read(),modify(k,tot,val);//MAKE-SAME
200         }
201         if(ch[0]=='R') rever(k,tot);//翻转 
202         if(ch[0]=='G') query(k,tot);//GET-SUM
203     }
204     return 0;
205 }
View Code

 

 

斌神的板子

  1 /**************************************************************
  2     Problem: 1500
  3     User: SongHL
  4     Language: C++
  5     Result: Accepted
  6     Time:6152 ms
  7     Memory:26684 kb
  8 ****************************************************************/
  9  
 10 #include<bits/stdc++.h>
 11 using namespace std;
 12  
 13 #define Key_value ch[ch[root][1]][0]
 14 const int MAXN = 500010;
 15 const int INF = 0x3f3f3f3f;
 16 int pre[MAXN],ch[MAXN][2],key[MAXN],size[MAXN];
 17 int root,tot1;
 18 int sum[MAXN],rev[MAXN],same[MAXN];
 19 int lx[MAXN],rx[MAXN],mx[MAXN];
 20 int s[MAXN],tot2;//内存池和容量
 21 int a[MAXN];
 22 int n,q;
 23  
 24 void NewNode(int &r,int father,int k)
 25 {
 26     if(tot2) r = s[tot2--];//取的时候是tot2--,存的时候就是++tot2
 27     else r = ++tot1;
 28     pre[r] = father;
 29     ch[r][0] = ch[r][1] = 0;
 30     key[r] = k;
 31     sum[r] = k;
 32     rev[r] = same[r] = 0;
 33     lx[r] = rx[r] = mx[r] = k;
 34     size[r] = 1;
 35 }
 36 void Update_Rev(int r)
 37 {
 38     if(!r)return;
 39     swap(ch[r][0],ch[r][1]);
 40     swap(lx[r],rx[r]);
 41     rev[r] ^= 1;
 42 }
 43 void Update_Same(int r,int v)
 44 {
 45     if(!r)return;
 46     key[r] = v;
 47     sum[r] = v*size[r];
 48     lx[r] = rx[r] = mx[r] = max(v,v*size[r]);
 49     same[r] = 1;
 50 }
 51 void push_up(int r)
 52 {
 53     int lson = ch[r][0], rson = ch[r][1];
 54     size[r] = size[lson] + size[rson] + 1;
 55     sum[r] = sum[lson] + sum[rson] + key[r];
 56     lx[r] = max(lx[lson],sum[lson] + key[r] + max(0,lx[rson]));
 57     rx[r] = max(rx[rson],sum[rson] + key[r] + max(0,rx[lson]));
 58     mx[r] = max(0,rx[lson]) + key[r] + max(0,lx[rson]);
 59     mx[r] = max(mx[r],max(mx[lson],mx[rson]));
 60 }
 61 void push_down(int r)
 62 {
 63     if(same[r])
 64     {
 65         Update_Same(ch[r][0],key[r]);
 66         Update_Same(ch[r][1],key[r]);
 67         same[r] = 0;
 68     }
 69     if(rev[r])
 70     {
 71         Update_Rev(ch[r][0]);
 72         Update_Rev(ch[r][1]);
 73         rev[r] = 0;
 74     }
 75 }
 76 void Build(int &x,int l,int r,int father)
 77 {
 78     if(l > r)return;
 79     int mid = (l+r)/2;
 80     NewNode(x,father,a[mid]);
 81     Build(ch[x][0],l,mid-1,x);
 82     Build(ch[x][1],mid+1,r,x);
 83     push_up(x);
 84 }
 85 void Init()
 86 {
 87     root = tot1 = tot2 = 0;
 88     ch[root][0] = ch[root][1] = size[root] = pre[root] = 0;
 89     same[root] = rev[root] = sum[root] = key[root] = 0;
 90     lx[root] = rx[root] = mx[root] = -INF;
 91     NewNode(root,0,-1);
 92     NewNode(ch[root][1],root,-1);
 93     for(int i = 0;i < n;i++)
 94         scanf("%d",&a[i]);
 95     Build(Key_value,0,n-1,ch[root][1]);
 96     push_up(ch[root][1]);
 97     push_up(root);
 98 }
 99 //旋转,0为左旋,1为右旋
100 void Rotate(int x,int kind)
101 {
102     int y = pre[x];
103     push_down(y);
104     push_down(x);
105     ch[y][!kind] = ch[x][kind];
106     pre[ch[x][kind]] = y;
107     if(pre[y])
108         ch[pre[y]][ch[pre[y]][1]==y] = x;
109     pre[x] = pre[y];
110     ch[x][kind] = y;
111     pre[y] = x;
112     push_up(y);
113 }
114 //Splay调整,将r结点调整到goal下面
115 void Splay(int r,int goal)
116 {
117     push_down(r);
118     while(pre[r] != goal)
119     {
120         if(pre[pre[r]] == goal)
121         {
122             push_down(pre[r]);
123             push_down(r);
124             Rotate(r,ch[pre[r]][0] == r);
125         }
126         else
127         {
128             push_down(pre[pre[r]]);
129             push_down(pre[r]);
130             push_down(r);
131             int y = pre[r];
132             int kind = ch[pre[y]][0]==y;
133             if(ch[y][kind] == r)
134             {
135                 Rotate(r,!kind);
136                 Rotate(r,kind);
137             }
138             else
139             {
140                 Rotate(y,kind);
141                 Rotate(r,kind);
142             }
143         }
144     }
145     push_up(r);
146     if(goal == 0) root = r;
147 }
148 int Get_kth(int r,int k)
149 {
150     push_down(r);
151     int t = size[ch[r][0]] + 1;
152     if(t == k)return r;
153     if(t > k)return Get_kth(ch[r][0],k);
154     else return Get_kth(ch[r][1],k-t);
155 }
156  
157 //在第pos个数后面插入tot个数
158 void Insert(int pos,int tot)
159 {
160     for(int i = 0;i < tot;i++)scanf("%d",&a[i]);
161     Splay(Get_kth(root,pos+1),0);
162     Splay(Get_kth(root,pos+2),root);
163     Build(Key_value,0,tot-1,ch[root][1]);
164     push_up(ch[root][1]);
165     push_up(root);
166 }
167  
168 //删除子树
169 void erase(int r)
170 {
171     if(!r)return;
172     s[++tot2] = r;
173     erase(ch[r][0]);
174     erase(ch[r][1]);
175 }
176 //从第pos个数开始连续删除tot个数
177 void Delete(int pos,int tot)
178 {
179     Splay(Get_kth(root,pos),0);
180     Splay(Get_kth(root,pos+tot+1),root);
181     erase(Key_value);
182     pre[Key_value] = 0;
183     Key_value = 0;
184     push_up(ch[root][1]);
185     push_up(root);
186 }
187 //将从第pos个数开始的连续的tot个数修改为c
188 void Make_Same(int pos,int tot,int c)
189 {
190     Splay(Get_kth(root,pos),0);
191     Splay(Get_kth(root,pos+tot+1),root);
192     Update_Same(Key_value,c);
193     push_up(ch[root][1]);
194     push_up(root);
195 }
196  
197 //将第pos个数开始的连续tot个数进行反转
198 void Reverse(int pos,int tot)
199 {
200     Splay(Get_kth(root,pos),0);
201     Splay(Get_kth(root,pos+tot+1),root);
202     Update_Rev(Key_value);
203     push_up(ch[root][1]);
204     push_up(root);
205 }
206 //得到第pos个数开始的tot个数的和
207 int Get_Sum(int pos,int tot)
208 {
209     Splay(Get_kth(root,pos),0);
210     Splay(Get_kth(root,pos+tot+1),root);
211     return sum[Key_value];
212 }
213 //得到第pos个数开始的tot个数中最大的子段和
214 int Get_MaxSum(int pos,int tot)
215 {
216     Splay(Get_kth(root,pos),0);
217     Splay(Get_kth(root,pos+tot+1),root);
218     return mx[Key_value];
219 }
220  
221 void InOrder(int r)
222 {
223     if(!r)return;
224     push_down(r);
225     InOrder(ch[r][0]);
226     printf("%d ",key[r]);
227     InOrder(ch[r][1]);
228 }
229  
230  
231  
232 int main()
233 {
234      while(scanf("%d%d",&n,&q) == 2)   
235     {
236         Init();
237         char op[20];
238         int x,y,z;
239         while(q--)
240         {
241             scanf("%s",op);
242             if(strcmp(op,"INSERT") == 0)
243             {
244                 scanf("%d%d",&x,&y);
245                 Insert(x,y);
246             }
247             else if(strcmp(op,"DELETE") == 0)
248             {
249                 scanf("%d%d",&x,&y);
250                 Delete(x,y);
251             }
252             else if(strcmp(op,"MAKE-SAME") == 0)
253             {
254                 scanf("%d%d%d",&x,&y,&z);
255                 Make_Same(x,y,z);
256             }
257             else if(strcmp(op,"REVERSE") == 0)
258             {
259                 scanf("%d%d",&x,&y);
260                 Reverse(x,y);
261             }
262             else if(strcmp(op,"GET-SUM") == 0)
263             {
264                 scanf("%d%d",&x,&y);
265                 printf("%d\n",Get_Sum(x,y));
266             }
267             else if(strcmp(op,"MAX-SUM") == 0)
268                 printf("%d\n",Get_MaxSum(1,size[root]-2));
269         }
270     }
271     return 0;
272 }
View Code

 

  

转载于:https://www.cnblogs.com/songorz/p/9808010.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/570287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何解决SVN 清理失败

解决方法&#xff1a; 下载 sqlite3.exe 在你的清理失败的路径下查看.svn目录下是否存在一个wc.db文件&#xff0c;把解压好的sqlite3.exe 放在wc.db文件的同一路径下 注意&#xff1a;主要是用sqlite3.exe清理掉wc.db中的相关信息。 通过cmd命令行进入你清理失败的路径&am…

10-Linux与windows文件互传-pscp坑---- 'pscp' 不是内部或外部命令,也不是可运行的程序或批处理文件...

1.下载pscp工具http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html2.拷贝到C:\Windows\System32 如果考到其他文件夹&#xff0c;运行提示 pscp 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 那么考到这个文件下吧&#xff01;&#xff0…

MongoDB最简单的入门教程之三 使用Java代码往MongoDB里插入数据

前两篇教程我们介绍了如何搭建MongoDB的本地环境&#xff1a; MongoDB最简单的入门教程之一 环境搭建 以及如何用nodejs读取MongoDB里的记录&#xff1a; MongoDB最简单的入门教程之二 使用nodejs访问MongoDB 这篇教程我们会介绍如何使用Java代码来连接MongoDB。 如果您是基于M…

C点滴成海------Dev C++怎么修改成简体中文

第一步&#xff1a;选择菜单中的Tools 第二步&#xff1a;选择Tools中的“Envirnoment Options”&#xff0c;即第二个选项 第三步&#xff1a;选择中文并保存 将"1"的语言改成中文就行了 转载于:https://www.cnblogs.com/hahayixiao/p/9824080.html

MacOS下安装BeautifulSoup库及使用

BeautifulSoup简介 BeautifulSoup库是一个强大的python第三方库&#xff0c;它可以解析html进行解析&#xff0c;并提取信息。 安装BeautifulSoup 打开终端&#xff0c;输入命令&#xff1a;pip3 install beautifulsoup4 BeautifulSoup库小测 小测用到的html页面地址&#xff1…

P4 类、对象、类成员简介

本节内容 类&#xff08;class&#xff09;是显示世界事物的模型。 现实中的一架飞机>>>抽象为程序世界中的类 类与对象的关系 对象也叫做实例&#xff0c;是类经过实例化得到的内存中的事宜 有些类不能被实例化&#xff0c;如数学&#xff0c;我们不能说一个数学依照…

PhpStorm之操作数据库

对数据库进行基本的操作 还不清楚如何使用PhpStorm连接本地数据库的朋友看一下我的上一篇博客配置数据库连接点击已经连接好的数据库&#xff0c;找到下图中的 Consoles&#xff0c;然后点击 console(default) 3.在完成上面的操作后&#xff0c;就会发现在编辑器的主页面出现了…

linux的一些基本命令

一、linux的一些基本命令&#xff08;使用的是CentOS7系统&#xff09;&#xff1a; 1、创建用户组&#xff0c;创建新用户并添加到用户组 添加用户&#xff0c;添加用户组命令&#xff1a; 增加用户&#xff1a;useradd -d /usr/username -m username    为用户增加密码&a…

springBoot+mybatisPlus小demo

项目介绍&#xff1a;采用restful api进行接口规范 / 项目框架SpringBootmybatis Plus / 采用mysql进行数据存储 / 采用swaggerUI进行前后端业务分离式开发。 开发环境&#xff1a;JDK1.8Mysql8.0.12IDEAL 实现功能&#xff1a;springboot搭建整体框架&#xff0c;MybatisPlus动…

[NOI1995]石子合并

题目描述&#xff1a; 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆&#xff0c;并将新的一堆的石子数&#xff0c;记为该次合并的得分。 试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分. 输入输出格…

docker+selenium grid解决node执行经常卡死

执行用例时出现下图&#xff1a; 可以在启动node节点容器时添加如下红色字体的参数 docker run -d -p 5903:5900 --shm-size512m --link selenium_hub:hub --name chrome_node-5903 -e NODE_MAX_INSTANCES5 -e NODE_MAX_SESSION5 selenium/node-chrome-debug 启动容器后到grid…

高级软件工程第四次作业:两只小熊队团队作业

一、团队展示 队名&#xff1a;两只小熊队 队员学号 周菲&#xff08;队长&#xff09;学号&#xff1a; 201810812007 孔繁燕&#xff08;队员&#xff09;学号&#xff1a;201810812001 一句话描述拟作的团队项目&#xff1a;充分发挥主动积极性&#xff0c;通过团队提升自我…

杂项:WCF

ylbtech-杂项&#xff1a;WCFWindows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架&#xff0c;可以翻译为Windows 通讯开发平台。整合了原有的windows通讯的 .net Remoting&#xff0c;WebService&#xff0c;Socket的机制&#xff0c;并融合…

jSignature开发实例

插件描述&#xff1a;jQuery手写签名插件jSignature &#xff0c;实现H5APP、网页 手写签名涂鸦 保存图片 代码实例 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP index.jsp starti…

json、xml

json&#xff1a;(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。简单地说&#xff0c;JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串&#xff0c;然后就可以在函数之间轻松地传递这个字符串&#xff0c;或者在异步应用程序中将字符串从 …

python中前后端通信方法Ajax和ORM映射(form表单提交)

后端从数据库获取数据给到前端&#xff1a; 第一种方式&#xff1a; admin.py文件代码&#xff1a; admin.route(/showList) def show():# 获取数据库所有文章数据&#xff0c;得到一个个对象resArticle.query.all()dicts[]# 将每一个对象转成字典并加入一个列表&#xff0c;再…

C#知识点总结系列:3、C#中Delegate和Event

一、Delegate委托可以理解为一个方法签名。 可以将方法作为另外一个方法的参数带入其中进行运算。在C#中我们有三种方式去创建委托&#xff0c;分别如下&#xff1a; public delegate void Print(string str);static void delegatemethod(string str){Console.WriteLine(str);}…

python的2种字符串格式化输出

字符串格式化代码&#xff08;typecode&#xff09; 法一&#xff1a; %格式使用下面的格式 %[(name)] [flags] [width][.precision] typecode (name)输出字典的value使用&#xff0c;这里的name是字典的key&#xff08;实际指定时&#xff0c;必须有外面的圆括号&#xff09; …

Python中字典合并的四种方法

字典是Python语言中唯一的映射类型。映射类型对象里哈希值&#xff08;键&#xff0c;key&#xff09;和指向的对象&#xff08;值&#xff0c;value&#xff09;是一对多的的关系&#xff0c;通常被认为是可变的哈希表。字典对象是可变的&#xff0c;它是一个容器类型&#xf…

从零开始的全栈工程师——js篇2.12(面向对象)

面向对象 Js一开始就是写网页特效&#xff0c;面向过程的&#xff0c;作者发现这样写不好&#xff0c;代码重复利用率太高&#xff0c;计算机内存消耗太大&#xff0c;网页性能很差。 所以作者就收到java和c的影响&#xff0c;往面向对象靠齐。Js天生有一个Object&#xff0c;但…